packages feed

Z-Botan 0.3.1.0 → 0.4.0.0

raw patch · 328 files changed

+6482/−5572 lines, 328 filesdep +primitivedep ~Z-Datasetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: primitive

Dependency ranges changed: Z-Data

API changes (from Hackage documentation)

- Z.Botan.FFI: botan_cipher_get_minimum_final_size :: BotanStructT -> MBA# Int -> IO CInt
- Z.Botan.FFI: botan_cipher_get_update_granularity :: BotanStructT -> MBA# Int -> IO CInt
- Z.Botan.FFI: botan_cipher_reset :: BotanStructT -> IO CInt
- Z.Botan.FFI: hs_botan_bcrypt_generate :: MBA# Word8 -> BA# Word8 -> Int -> Int -> BotanStructT -> Int -> Word32 -> IO Int
- Z.Botan.FFI: hs_botan_block_cipher_set_key :: BotanStructT -> BA# Word8 -> Int -> Int -> IO CInt
- Z.Botan.FFI: hs_botan_cipher_set_key :: BotanStructT -> BA# Word8 -> Int -> Int -> IO CInt
- Z.Botan.FFI: hs_botan_cipher_update :: BotanStructT -> MBA# Word8 -> BA# Word8 -> Int -> Int -> IO Int
- Z.Botan.FFI: hs_botan_hex_decode :: BA# Word8 -> Int -> Int -> MBA# Word8 -> IO ()
- Z.Botan.FFI: hs_botan_hex_encode :: BA# Word8 -> Int -> Int -> MBA# Word8 -> IO ()
- Z.Botan.FFI: hs_botan_hex_encode_lower :: BA# Word8 -> Int -> Int -> MBA# Word8 -> IO ()
- Z.Botan.FFI: hs_botan_key_wrap3394 :: BA# Word8 -> Int -> Int -> BA# Word8 -> Int -> Int -> MBA# Word8 -> MBA# CSize -> IO CInt
- Z.Botan.FFI: hs_botan_mac_set_key :: BotanStructT -> BA# Word8 -> Int -> Int -> IO CInt
- Z.Crypto.Cipher: cipherBIO :: HasCallStack => Cipher -> IO (BIO Bytes Bytes)
- Z.Crypto.Cipher: cipherUpdateGranularity :: Cipher -> Int
- Z.Crypto.Cipher: finishCipher :: HasCallStack => Cipher -> Bytes -> IO Bytes
- Z.Crypto.Cipher: resetCipher :: HasCallStack => Cipher -> IO ()
- Z.Crypto.Cipher: setAssociatedData :: HasCallStack => Cipher -> Bytes -> IO ()
- Z.Crypto.Cipher: startCipher :: HasCallStack => Cipher -> Bytes -> IO ()
- Z.Crypto.Cipher: updateCipher :: HasCallStack => Cipher -> Bytes -> IO (Bytes, Bytes)
+ Z.Botan.FFI: botan_bcrypt_generate :: MBA# Word8 -> MBA# CSize -> BA# Word8 -> BotanStructT -> Int -> Word32 -> IO CInt
+ Z.Botan.FFI: botan_block_cipher_set_key :: BotanStructT -> Ptr Word8 -> CSize -> IO CInt
+ Z.Botan.FFI: botan_cipher_set_key :: BotanStructT -> Ptr Word8 -> CSize -> IO CInt
+ Z.Botan.FFI: botan_constant_time_compare :: Ptr Word8 -> Ptr Word8 -> CSize -> CInt
+ Z.Botan.FFI: botan_constant_time_compare_ba :: BA# Word8 -> BA# Word8 -> CSize -> CInt
+ Z.Botan.FFI: botan_key_wrap3394 :: Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> MBA# Word8 -> MBA# CSize -> IO CInt
+ Z.Botan.FFI: botan_mac_set_key :: BotanStructT -> Ptr Word8 -> CSize -> IO CInt
+ Z.Botan.FFI: botan_stream_cipher_clear :: BotanStructT -> IO CInt
+ Z.Botan.FFI: botan_stream_cipher_destroy :: FunPtr (BotanStructT -> IO ())
+ Z.Botan.FFI: botan_stream_cipher_get_default_iv_length :: BotanStructT -> MBA# Int -> IO CInt
+ Z.Botan.FFI: botan_stream_cipher_get_keyspec :: BotanStructT -> MBA# CSize -> MBA# CSize -> MBA# CSize -> IO CInt
+ Z.Botan.FFI: botan_stream_cipher_init :: MBA# BotanStructT -> BA# Word8 -> IO CInt
+ Z.Botan.FFI: botan_stream_cipher_seek :: BotanStructT -> CSize -> IO CInt
+ Z.Botan.FFI: botan_stream_cipher_set_key :: BotanStructT -> Ptr Word8 -> CSize -> IO CInt
+ Z.Botan.FFI: botan_stream_cipher_valid_iv_length :: BotanStructT -> CSize -> IO CInt
+ Z.Botan.FFI: botan_stream_cipher_write_keystream :: BotanStructT -> MBA# Word8 -> CSize -> IO CInt
+ Z.Botan.FFI: hs_botan_allocate_memory :: Int -> IO (Ptr Word8)
+ Z.Botan.FFI: hs_botan_cipher_output_size :: BotanStructT -> Int -> IO Int
+ Z.Botan.FFI: hs_botan_deallocate_memory :: Ptr Word8 -> Ptr Word8 -> IO ()
+ Z.Botan.FFI: hs_botan_deallocate_memory_p :: FunPtr (Ptr Word8 -> Ptr Word8 -> IO ())
+ Z.Botan.FFI: hs_botan_stream_cipher_cipher :: BotanStructT -> MBA# Word8 -> BA# Word8 -> Int -> Int -> IO CInt
+ Z.Botan.FFI: hs_botan_stream_cipher_set_iv :: BotanStructT -> BA# Word8 -> Int -> Int -> IO CInt
+ Z.Crypto.Cipher: Adler32 :: HashType
+ Z.Crypto.Cipher: BLAKE2b :: Int -> HashType
+ Z.Crypto.Cipher: BLAKE2b256 :: HashType
+ Z.Crypto.Cipher: BLAKE2b512 :: HashType
+ Z.Crypto.Cipher: CCM' :: BlockCipherType -> Int -> Int -> CipherMode
+ Z.Crypto.Cipher: CFB' :: BlockCipherType -> Int -> CipherMode
+ Z.Crypto.Cipher: CRC24 :: HashType
+ Z.Crypto.Cipher: CRC32 :: HashType
+ Z.Crypto.Cipher: Comb4P :: HashType -> HashType -> HashType
+ Z.Crypto.Cipher: EAX' :: BlockCipherType -> Int -> CipherMode
+ Z.Crypto.Cipher: GCM' :: BlockCipherType -> Int -> CipherMode
+ Z.Crypto.Cipher: Keccak1600_224 :: HashType
+ Z.Crypto.Cipher: Keccak1600_256 :: HashType
+ Z.Crypto.Cipher: Keccak1600_384 :: HashType
+ Z.Crypto.Cipher: Keccak1600_512 :: HashType
+ Z.Crypto.Cipher: MD4 :: HashType
+ Z.Crypto.Cipher: MD5 :: HashType
+ Z.Crypto.Cipher: OCB' :: BlockCipherType -> Int -> CipherMode
+ Z.Crypto.Cipher: Parallel :: HashType -> HashType -> HashType
+ Z.Crypto.Cipher: RIPEMD160 :: HashType
+ Z.Crypto.Cipher: SHA160 :: HashType
+ Z.Crypto.Cipher: SHA224 :: HashType
+ Z.Crypto.Cipher: SHA256 :: HashType
+ Z.Crypto.Cipher: SHA384 :: HashType
+ Z.Crypto.Cipher: SHA3_224 :: HashType
+ Z.Crypto.Cipher: SHA3_256 :: HashType
+ Z.Crypto.Cipher: SHA3_384 :: HashType
+ Z.Crypto.Cipher: SHA3_512 :: HashType
+ Z.Crypto.Cipher: SHA512 :: HashType
+ Z.Crypto.Cipher: SHA512_256 :: HashType
+ Z.Crypto.Cipher: SHAKE128 :: Int -> HashType
+ Z.Crypto.Cipher: SHAKE256 :: Int -> HashType
+ Z.Crypto.Cipher: SM3 :: HashType
+ Z.Crypto.Cipher: Skein512 :: Int -> CBytes -> HashType
+ Z.Crypto.Cipher: Streebog256 :: HashType
+ Z.Crypto.Cipher: Streebog512 :: HashType
+ Z.Crypto.Cipher: Whirlpool :: HashType
+ Z.Crypto.Cipher: clearStreamCipher :: HasCallStack => StreamCipher -> IO ()
+ Z.Crypto.Cipher: data HashType
+ Z.Crypto.Cipher: data StreamCipher
+ Z.Crypto.Cipher: defaultIVLength :: StreamCipher -> Int
+ Z.Crypto.Cipher: instance GHC.Generics.Generic Z.Crypto.Cipher.StreamCipher
+ Z.Crypto.Cipher: instance GHC.Show.Show Z.Crypto.Cipher.StreamCipher
+ Z.Crypto.Cipher: instance Z.Data.Text.Print.Print Z.Crypto.Cipher.StreamCipher
+ Z.Crypto.Cipher: keyStreamSource :: HasCallStack => StreamCipher -> Int -> Source Bytes
+ Z.Crypto.Cipher: runCipher :: HasCallStack => Cipher -> Nonce -> Bytes -> Bytes -> IO Bytes
+ Z.Crypto.Cipher: runStreamCipher :: HasCallStack => StreamCipher -> Bytes -> IO Bytes
+ Z.Crypto.Cipher: seekStreamCipher :: StreamCipher -> Int -> IO ()
+ Z.Crypto.Cipher: setStreamCipherIV :: StreamCipher -> Nonce -> IO ()
+ Z.Crypto.Cipher: setStreamCipherKey :: HasCallStack => StreamCipher -> Secret -> IO ()
+ Z.Crypto.Cipher: streamCipherBIO :: HasCallStack => StreamCipher -> BIO Bytes Bytes
+ Z.Crypto.Cipher: streamCipherKeySpec :: StreamCipher -> KeySpec
+ Z.Crypto.Cipher: streamCipherKeyStream :: HasCallStack => StreamCipher -> Int -> IO Bytes
+ Z.Crypto.Cipher: streamCipherName :: StreamCipher -> CBytes
+ Z.Crypto.Cipher: withStreamCipher :: StreamCipher -> (BotanStructT -> IO r) -> IO r
+ Z.Crypto.MAC: AES128 :: BlockCipherType
+ Z.Crypto.MAC: AES192 :: BlockCipherType
+ Z.Crypto.MAC: AES256 :: BlockCipherType
+ Z.Crypto.MAC: ARIA128 :: BlockCipherType
+ Z.Crypto.MAC: ARIA192 :: BlockCipherType
+ Z.Crypto.MAC: ARIA256 :: BlockCipherType
+ Z.Crypto.MAC: Adler32 :: HashType
+ Z.Crypto.MAC: BLAKE2b :: Int -> HashType
+ Z.Crypto.MAC: BLAKE2b256 :: HashType
+ Z.Crypto.MAC: BLAKE2b512 :: HashType
+ Z.Crypto.MAC: Blowfish :: BlockCipherType
+ Z.Crypto.MAC: CAST128 :: BlockCipherType
+ Z.Crypto.MAC: CAST256 :: BlockCipherType
+ Z.Crypto.MAC: CRC24 :: HashType
+ Z.Crypto.MAC: CRC32 :: HashType
+ Z.Crypto.MAC: Camellia128 :: BlockCipherType
+ Z.Crypto.MAC: Camellia192 :: BlockCipherType
+ Z.Crypto.MAC: Camellia256 :: BlockCipherType
+ Z.Crypto.MAC: Cascade :: BlockCipherType -> BlockCipherType -> BlockCipherType
+ Z.Crypto.MAC: Comb4P :: HashType -> HashType -> HashType
+ Z.Crypto.MAC: DES :: BlockCipherType
+ Z.Crypto.MAC: DESX :: BlockCipherType
+ Z.Crypto.MAC: IDEA :: BlockCipherType
+ Z.Crypto.MAC: KASUMI :: BlockCipherType
+ Z.Crypto.MAC: Keccak1600_224 :: HashType
+ Z.Crypto.MAC: Keccak1600_256 :: HashType
+ Z.Crypto.MAC: Keccak1600_384 :: HashType
+ Z.Crypto.MAC: Keccak1600_512 :: HashType
+ Z.Crypto.MAC: Lion :: HashType -> StreamCipherType -> Int -> BlockCipherType
+ Z.Crypto.MAC: MD4 :: HashType
+ Z.Crypto.MAC: MD5 :: HashType
+ Z.Crypto.MAC: MISTY1 :: BlockCipherType
+ Z.Crypto.MAC: Noekeon :: BlockCipherType
+ Z.Crypto.MAC: Parallel :: HashType -> HashType -> HashType
+ Z.Crypto.MAC: RIPEMD160 :: HashType
+ Z.Crypto.MAC: SEED :: BlockCipherType
+ Z.Crypto.MAC: SHA160 :: HashType
+ Z.Crypto.MAC: SHA224 :: HashType
+ Z.Crypto.MAC: SHA256 :: HashType
+ Z.Crypto.MAC: SHA384 :: HashType
+ Z.Crypto.MAC: SHA3_224 :: HashType
+ Z.Crypto.MAC: SHA3_256 :: HashType
+ Z.Crypto.MAC: SHA3_384 :: HashType
+ Z.Crypto.MAC: SHA3_512 :: HashType
+ Z.Crypto.MAC: SHA512 :: HashType
+ Z.Crypto.MAC: SHA512_256 :: HashType
+ Z.Crypto.MAC: SHACAL2 :: BlockCipherType
+ Z.Crypto.MAC: SHAKE128 :: Int -> HashType
+ Z.Crypto.MAC: SHAKE256 :: Int -> HashType
+ Z.Crypto.MAC: SM3 :: HashType
+ Z.Crypto.MAC: SM4 :: BlockCipherType
+ Z.Crypto.MAC: Serpent :: BlockCipherType
+ Z.Crypto.MAC: Skein512 :: Int -> CBytes -> HashType
+ Z.Crypto.MAC: Streebog256 :: HashType
+ Z.Crypto.MAC: Streebog512 :: HashType
+ Z.Crypto.MAC: Threefish512 :: BlockCipherType
+ Z.Crypto.MAC: TripleDES :: BlockCipherType
+ Z.Crypto.MAC: Twofish :: BlockCipherType
+ Z.Crypto.MAC: Whirlpool :: HashType
+ Z.Crypto.MAC: XTEA :: BlockCipherType
+ Z.Crypto.MAC: data BlockCipherType
+ Z.Crypto.MAC: data HashType
+ Z.Crypto.SafeMem: CEBytes :: PrimArray Word8 -> CEBytes
+ Z.Crypto.SafeMem: PasswordContainsControlCharacter :: CallStack -> InvalidPasswordException
+ Z.Crypto.SafeMem: ceBytes :: Bytes -> CEBytes
+ Z.Crypto.SafeMem: ceBytesBitSize :: CEBytes -> Int
+ Z.Crypto.SafeMem: ceBytesSize :: CEBytes -> Int
+ Z.Crypto.SafeMem: cnt32bitNonce :: Int32 -> Nonce
+ Z.Crypto.SafeMem: cnt64bitNonce :: Int64 -> Nonce
+ Z.Crypto.SafeMem: data InvalidPasswordException
+ Z.Crypto.SafeMem: data Password
+ Z.Crypto.SafeMem: data Secret
+ Z.Crypto.SafeMem: instance Data.String.IsString Z.Crypto.SafeMem.Password
+ Z.Crypto.SafeMem: instance Data.String.IsString Z.Crypto.SafeMem.Secret
+ Z.Crypto.SafeMem: instance GHC.Classes.Eq Z.Crypto.SafeMem.CEBytes
+ Z.Crypto.SafeMem: instance GHC.Classes.Eq Z.Crypto.SafeMem.Secret
+ Z.Crypto.SafeMem: instance GHC.Exception.Type.Exception Z.Crypto.SafeMem.InvalidPasswordException
+ Z.Crypto.SafeMem: instance GHC.Show.Show Z.Crypto.SafeMem.CEBytes
+ Z.Crypto.SafeMem: instance GHC.Show.Show Z.Crypto.SafeMem.InvalidPasswordException
+ Z.Crypto.SafeMem: instance GHC.Show.Show Z.Crypto.SafeMem.Password
+ Z.Crypto.SafeMem: instance GHC.Show.Show Z.Crypto.SafeMem.Secret
+ Z.Crypto.SafeMem: instance Z.Data.Text.Print.Print Z.Crypto.SafeMem.CEBytes
+ Z.Crypto.SafeMem: instance Z.Data.Text.Print.Print Z.Crypto.SafeMem.Password
+ Z.Crypto.SafeMem: instance Z.Data.Text.Print.Print Z.Crypto.SafeMem.Secret
+ Z.Crypto.SafeMem: mkPassword :: HasCallStack => Text -> Password
+ Z.Crypto.SafeMem: mkPasswordMaybe :: Text -> Maybe Password
+ Z.Crypto.SafeMem: newCEBytesSafe :: Int -> (Ptr Word8 -> IO r) -> IO CEBytes
+ Z.Crypto.SafeMem: newCEBytesUnsafe :: Int -> (MBA# Word8 -> IO r) -> IO CEBytes
+ Z.Crypto.SafeMem: newSecret :: Int -> (Ptr Word8 -> IO r) -> IO Secret
+ Z.Crypto.SafeMem: newtype CEBytes
+ Z.Crypto.SafeMem: passwordSize :: Password -> Int
+ Z.Crypto.SafeMem: passwordToText :: Password -> Text
+ Z.Crypto.SafeMem: rand128bitNonce :: RNG -> IO Nonce
+ Z.Crypto.SafeMem: rand192bitNonce :: RNG -> IO Nonce
+ Z.Crypto.SafeMem: rand96bitNonce :: RNG -> IO Nonce
+ Z.Crypto.SafeMem: secretBitSize :: Secret -> Int
+ Z.Crypto.SafeMem: secretSize :: Secret -> Int
+ Z.Crypto.SafeMem: type Nonce = Bytes
+ Z.Crypto.SafeMem: unCEBytes :: CEBytes -> Bytes
+ Z.Crypto.SafeMem: unsafeSecretFromBytes :: Bytes -> IO Secret
+ Z.Crypto.SafeMem: unsafeSecretToBytes :: Secret -> IO Bytes
+ Z.Crypto.SafeMem: withPasswordSafe :: Password -> (Ptr Word8 -> IO r) -> IO r
+ Z.Crypto.SafeMem: withPasswordUnsafe :: Password -> (BA# Word8 -> IO r) -> IO r
+ Z.Crypto.SafeMem: withSecret :: Secret -> (Ptr Word8 -> CSize -> IO r) -> IO r
- Z.Botan.FFI: botan_cipher_get_keyspec :: BotanStructT -> MBA# Int -> MBA# Int -> MBA# Int -> IO CInt
+ Z.Botan.FFI: botan_cipher_get_keyspec :: BotanStructT -> MBA# CSize -> MBA# CSize -> MBA# CSize -> IO CInt
- Z.Botan.FFI: botan_pk_op_key_agreement_export_public :: BotanStructT -> MBA# Word8 -> MBA# Int -> IO CInt
+ Z.Botan.FFI: botan_pk_op_key_agreement_export_public :: BotanStructT -> MBA# Word8 -> MBA# CSize -> IO CInt
- Z.Botan.FFI: botan_pk_op_sign_finish :: BotanStructT -> BotanStructT -> MBA# Word8 -> MBA# Int -> IO CInt
+ Z.Botan.FFI: botan_pk_op_sign_finish :: BotanStructT -> BotanStructT -> MBA# Word8 -> MBA# CSize -> IO CInt
- Z.Botan.FFI: hs_botan_bcrypt_is_valid :: BA# Word8 -> Int -> Int -> BA# Word8 -> Int -> Int -> IO CInt
+ Z.Botan.FFI: hs_botan_bcrypt_is_valid :: BA# Word8 -> BA# Word8 -> Int -> Int -> IO CInt
- Z.Botan.FFI: hs_botan_kdf :: BA# Word8 -> MBA# Word8 -> Int -> BA# Word8 -> Int -> Int -> BA# Word8 -> Int -> Int -> BA# Word8 -> Int -> Int -> IO CInt
+ Z.Botan.FFI: hs_botan_kdf :: BA# Word8 -> Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> BA# Word8 -> Int -> Int -> BA# Word8 -> Int -> Int -> IO CInt
- Z.Botan.FFI: hs_botan_key_unwrap3394 :: BA# Word8 -> Int -> Int -> BA# Word8 -> Int -> Int -> MBA# Word8 -> MBA# CSize -> IO CInt
+ Z.Botan.FFI: hs_botan_key_unwrap3394 :: BA# Word8 -> Int -> Int -> Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> IO CInt
- Z.Botan.FFI: hs_botan_pk_op_decrypt :: BotanStructT -> MBA# Word8 -> MBA# Int -> BA# Word8 -> Int -> Int -> IO CInt
+ Z.Botan.FFI: hs_botan_pk_op_decrypt :: BotanStructT -> MBA# Word8 -> MBA# CSize -> BA# Word8 -> Int -> Int -> IO CInt
- Z.Botan.FFI: hs_botan_pk_op_encrypt :: BotanStructT -> BotanStructT -> MBA# Word8 -> MBA# Int -> BA# Word8 -> Int -> Int -> IO CInt
+ Z.Botan.FFI: hs_botan_pk_op_encrypt :: BotanStructT -> BotanStructT -> MBA# Word8 -> MBA# CSize -> BA# Word8 -> Int -> Int -> IO CInt
- Z.Botan.FFI: hs_botan_pk_op_key_agreement :: BotanStructT -> MBA# Word8 -> MBA# Int -> BA# Word8 -> Int -> Int -> BA# Word8 -> Int -> Int -> IO CInt
+ Z.Botan.FFI: hs_botan_pk_op_key_agreement :: BotanStructT -> Ptr Word8 -> CSize -> BA# Word8 -> Int -> Int -> BA# Word8 -> Int -> Int -> IO CInt
- Z.Botan.FFI: hs_botan_pwdhash :: BA# Word8 -> Int -> Int -> Int -> MBA# Word8 -> Int -> BA# Word8 -> Int -> BA# Word8 -> Int -> Int -> IO CInt
+ Z.Botan.FFI: hs_botan_pwdhash :: BA# Word8 -> Int -> Int -> Int -> Ptr Word8 -> Int -> BA# Word8 -> Int -> BA# Word8 -> Int -> Int -> IO CInt
- Z.Botan.FFI: hs_botan_pwdhash_timed :: BA# Word8 -> Int -> MBA# Word8 -> Int -> BA# Word8 -> Int -> BA# Word8 -> Int -> Int -> IO CInt
+ Z.Botan.FFI: hs_botan_pwdhash_timed :: BA# Word8 -> Int -> Ptr Word8 -> Int -> BA# Word8 -> Int -> BA# Word8 -> Int -> Int -> IO CInt
- Z.Crypto.Cipher: CFB :: BlockCipherType -> Int -> CipherMode
+ Z.Crypto.Cipher: CFB :: BlockCipherType -> CipherMode
- Z.Crypto.Cipher: newStreamCipher :: HasCallStack => StreamCipherType -> CipherDirection -> IO Cipher
+ Z.Crypto.Cipher: newStreamCipher :: HasCallStack => StreamCipherType -> IO StreamCipher
- Z.Crypto.Cipher: setBlockCipherKey :: HasCallStack => BlockCipher -> Bytes -> IO ()
+ Z.Crypto.Cipher: setBlockCipherKey :: HasCallStack => BlockCipher -> Secret -> IO ()
- Z.Crypto.Cipher: setCipherKey :: HasCallStack => Cipher -> Bytes -> IO ()
+ Z.Crypto.Cipher: setCipherKey :: HasCallStack => Cipher -> Secret -> IO ()
- Z.Crypto.Hash: finalHash :: HasCallStack => Hash -> IO Bytes
+ Z.Crypto.Hash: finalHash :: HasCallStack => Hash -> IO CEBytes
- Z.Crypto.Hash: hash :: HasCallStack => HashType -> Bytes -> Bytes
+ Z.Crypto.Hash: hash :: HasCallStack => HashType -> Bytes -> CEBytes
- Z.Crypto.Hash: hashChunks :: HasCallStack => HashType -> [Bytes] -> Bytes
+ Z.Crypto.Hash: hashChunks :: HasCallStack => HashType -> [Bytes] -> CEBytes
- Z.Crypto.KDF: kdf :: HasCallStack => KDFType -> Int -> Bytes -> Bytes -> Bytes -> IO Bytes
+ Z.Crypto.KDF: kdf :: HasCallStack => KDFType -> Int -> Secret -> Bytes -> Bytes -> IO Secret
- Z.Crypto.KDF: kdf' :: HasCallStack => KDFType -> Int -> Bytes -> IO Bytes
+ Z.Crypto.KDF: kdf' :: HasCallStack => KDFType -> Int -> Secret -> IO Secret
- Z.Crypto.KDF: pbkdf :: HasCallStack => PBKDFType -> Int -> CBytes -> Bytes -> IO Bytes
+ Z.Crypto.KDF: pbkdf :: HasCallStack => PBKDFType -> Int -> Password -> Bytes -> IO Secret
- Z.Crypto.KDF: pbkdfTimed :: HasCallStack => PBKDFType -> Int -> Int -> CBytes -> Bytes -> IO Bytes
+ Z.Crypto.KDF: pbkdfTimed :: HasCallStack => PBKDFType -> Int -> Int -> CBytes -> Bytes -> IO Secret
- Z.Crypto.KeyWrap: keyUnwrap :: HasCallStack => Bytes -> Bytes -> IO Bytes
+ Z.Crypto.KeyWrap: keyUnwrap :: HasCallStack => Bytes -> Secret -> IO Secret
- Z.Crypto.KeyWrap: keyWrap :: HasCallStack => Bytes -> Bytes -> IO Bytes
+ Z.Crypto.KeyWrap: keyWrap :: HasCallStack => Secret -> Secret -> IO Bytes
- Z.Crypto.MAC: finalMAC :: HasCallStack => MAC -> IO Bytes
+ Z.Crypto.MAC: finalMAC :: HasCallStack => MAC -> IO CEBytes
- Z.Crypto.MAC: mac :: HasCallStack => MACType -> Bytes -> Bytes -> Bytes
+ Z.Crypto.MAC: mac :: HasCallStack => MACType -> Secret -> Bytes -> CEBytes
- Z.Crypto.MAC: macChunks :: HasCallStack => MACType -> Bytes -> [Bytes] -> Bytes
+ Z.Crypto.MAC: macChunks :: HasCallStack => MACType -> Secret -> [Bytes] -> CEBytes
- Z.Crypto.MAC: setKeyMAC :: HasCallStack => MAC -> Bytes -> IO ()
+ Z.Crypto.MAC: setKeyMAC :: HasCallStack => MAC -> Secret -> IO ()
- Z.Crypto.PubKey: keyAgree :: HasCallStack => KeyAgreement -> Bytes -> Bytes -> IO Bytes
+ Z.Crypto.PubKey: keyAgree :: HasCallStack => KeyAgreement -> Bytes -> Bytes -> IO Secret
- Z.Crypto.PwdHash: genBcrypt :: HasCallStack => Bytes -> RNG -> Int -> IO Bytes
+ Z.Crypto.PwdHash: genBcrypt :: HasCallStack => Password -> RNG -> Int -> IO Bytes
- Z.Crypto.PwdHash: validBcrypt :: HasCallStack => Bytes -> Bytes -> IO Bool
+ Z.Crypto.PwdHash: validBcrypt :: HasCallStack => Password -> Bytes -> IO Bool

Files

ChangeLog.md view
@@ -1,5 +1,15 @@ # Revision history for z-botan +## 0.4.0.0  -- 2020-06-06++* Add `Z.Crypto.SafeMem` module to improve memory safety:+    * Add `Password` type to enforce compare password by using password hash.+    * Add `CEBytes` with contant time equal comparing.+    * Add `Secret` with OS locking and auto zeroing.+* Add `StreamCipher` to `Z.Crypto.Cipher`, change `cipherBIO` to `streamCipherBIO` to use `StreamCipher` only.+* Rewrite AEAD/cipher mode interface to expose AEAD API only.+* Add more tests.+ ## 0.3.1.0  -- 2020-05-14  * Change `cipherBIO` to buffer an extra chunk so that the last chunk is larger than minimum final chunk size, add a file encryption example.
README.md view
@@ -29,7 +29,7 @@  ## Requirements -* A working haskell compiler system, GHC(>=8.6), cabal-install(>=2.4), hsc2hs.+* A working haskell compiler system, GHC(>=8.6), cabal-install(>=3.2.1), hsc2hs.  * A working python interpreter in `$PATH`. @@ -39,11 +39,9 @@  ```haskell > :set -XOverloadedLists-> :m + Z.Crypto.Hash Z.Data.Vector.Hex +> :m + Z.Crypto.Hash  >-> hash MD5 "hello, world"-[228,215,241,180,237,46,66,209,88,152,244,178,123,1,157,164]-> HexBytes $ hash SHA256  "hello, world"+> hash SHA256 "hello, world" 09CA7E4EAA6E8AE9C7D261167129184883644D07DFBA7CBFBC4C8A2E08360D5B > > :m + Z.Crypto.RNG Z.Crypto.PwdHash 
Setup.hs view
@@ -42,10 +42,10 @@                  postConf simpleUserHooks args flags pkg_descr lbi         ,   regHook = \ _ _ _ _ -> return ()-#if __GLASGOW_HASKELL__ < 810-        } (mainArgs)-#else+#if !MIN_VERSION_Cabal(3,2,1)         } mainArgs+#else+        } ("--ghc-options":"-optcxx-std=c++11":mainArgs) #endif     else defaultMain 
Z-Botan.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               Z-Botan-version:            0.3.1.0+version:            0.4.0.0 synopsis:           Crypto for Haskell description:        Crypto for Haskell, based on <http://botan.randombit.net/ Botan> license:            BSD-3-Clause@@ -58,6 +58,7 @@     Z.Crypto.PubKey     Z.Crypto.PwdHash     Z.Crypto.RNG+    Z.Crypto.SafeMem     Z.Crypto.X509   other-modules:    Paths_Z_Botan   autogen-modules:  Paths_Z_Botan@@ -69,18 +70,18 @@     , scientific   ^>=0.3     , stm          ^>=2.5     , time         == 1.11.*-    , Z-Data       >=0.8.2 && < 0.9+    , primitive    == 0.7.*+    , Z-Data       >=0.8.5 && < 0.9     , Z-IO         >=0.8 && < 0.9    include-dirs:-    include third_party/botan third_party/botan/build/include+    third_party/botan third_party/botan/build/include     third_party/botan/build/include/external -  includes:           hs_botan.h-  install-includes:   hs_botan.h-  c-sources:          cbits/hs_botan.c-  cc-options:         -march=native   cxx-sources:        third_party/botan/botan_all.cpp+                      cbits/hs_botan_extra.cpp+                      cbits/hs_botan_certstore.cpp+                      cbits/hs_botan_streamcipher.cpp    if os(windows)     extra-libraries:@@ -99,6 +100,7 @@    if os(osx)     extra-libraries: c+++    frameworks: CoreServices    else     extra-libraries: stdc++
Z/Botan/Errno.hsc view
@@ -15,7 +15,7 @@  import Foreign.C.Types -#include "hs_botan.h"+#include <botan/ffi.h>  -- | Generally returned to indicate success pattern BOTAN_FFI_SUCCESS                         :: CInt
Z/Botan/FFI.hsc view
@@ -27,14 +27,18 @@ import           Z.Foreign import           Z.Foreign.CPtr -#include "hs_botan.h"+#include <botan/ffi.h>  -------------------------------------------------------------------------------- -foreign import ccall unsafe hs_botan_hex_encode :: BA## Word8 -> Int -> Int -> MBA## Word8 -> IO ()-foreign import ccall unsafe hs_botan_hex_encode_lower :: BA## Word8 -> Int -> Int -> MBA## Word8 -> IO ()-foreign import ccall unsafe hs_botan_hex_decode :: BA## Word8 -> Int -> Int -> MBA## Word8 -> IO ()+foreign import ccall unsafe hs_botan_allocate_memory :: Int -> IO (Ptr Word8)+foreign import ccall unsafe "&hs_botan_deallocate_memory" hs_botan_deallocate_memory_p :: FunPtr (Ptr Word8 -> Ptr Word8 -> IO ())+foreign import ccall unsafe hs_botan_deallocate_memory :: Ptr Word8 -> Ptr Word8 -> IO () +foreign import ccall unsafe "botan_constant_time_compare" botan_constant_time_compare_ba :: BA## Word8 -> BA## Word8 -> CSize -> CInt+foreign import ccall unsafe botan_constant_time_compare :: Ptr Word8 -> Ptr Word8 -> CSize -> CInt++ allocBotanBufferUTF8Unsafe :: (HasCallStack, Integral r)                            => Int -> (MBA## Word8 -> MBA## CSize -> IO r) -> IO T.Text allocBotanBufferUTF8Unsafe len f = T.validate . V.unsafeInit <$> allocBotanBufferUnsafe len f@@ -142,8 +146,7 @@                                                            -> MBA## Int   -- ^ keylength_modulo                                                            -> IO CInt foreign import ccall unsafe botan_block_cipher_clear :: BotanStructT -> IO CInt-foreign import ccall unsafe hs_botan_block_cipher_set_key-    :: BotanStructT -> BA## Word8 -> Int -> Int -> IO CInt+foreign import ccall unsafe botan_block_cipher_set_key :: BotanStructT -> Ptr Word8 -> CSize -> IO CInt foreign import ccall unsafe hs_botan_block_cipher_encrypt_blocks     :: BotanStructT     -> BA## Word8   -- ^ in_buf@@ -184,23 +187,14 @@ foreign import ccall unsafe "&botan_cipher_destroy"     botan_cipher_destroy :: FunPtr (BotanStructT -> IO ()) foreign import ccall unsafe botan_cipher_clear :: BotanStructT -> IO CInt-foreign import ccall unsafe botan_cipher_reset :: BotanStructT -> IO CInt foreign import ccall unsafe botan_cipher_get_keyspec :: BotanStructT-                                                     -> MBA## Int   -- ^ minimum_keylength-                                                     -> MBA## Int   -- ^ maximum_keylength-                                                     -> MBA## Int   -- ^ keylength_modulo+                                                     -> MBA## CSize   -- ^ minimum_keylength+                                                     -> MBA## CSize   -- ^ maximum_keylength+                                                     -> MBA## CSize   -- ^ keylength_modulo                                                      -> IO CInt-foreign import ccall unsafe hs_botan_cipher_set_key-    :: BotanStructT -> BA## Word8 -> Int -> Int -> IO CInt+foreign import ccall unsafe botan_cipher_set_key :: BotanStructT -> Ptr Word8 -> CSize -> IO CInt foreign import ccall unsafe hs_botan_cipher_start     :: BotanStructT -> BA## Word8 -> Int -> Int -> IO CInt-foreign import ccall unsafe hs_botan_cipher_update-    :: BotanStructT-    -> MBA## Word8  -- ^ output-    -> BA## Word8   -- ^ input-    -> Int          -- ^ input offset-    -> Int          -- ^ input len-    -> IO Int       -- ^ output written  foreign import ccall unsafe hs_botan_cipher_finish     :: BotanStructT@@ -216,23 +210,54 @@  foreign import ccall unsafe botan_cipher_valid_nonce_length :: BotanStructT -> CSize -> IO CInt foreign import ccall unsafe botan_cipher_get_default_nonce_length :: BotanStructT -> MBA## Int -> IO CInt-foreign import ccall unsafe botan_cipher_get_update_granularity :: BotanStructT -> MBA## Int -> IO CInt foreign import ccall unsafe botan_cipher_get_tag_length :: BotanStructT -> MBA## Int -> IO CInt-foreign import ccall unsafe botan_cipher_get_minimum_final_size :: BotanStructT -> MBA## Int -> IO CInt+foreign import ccall unsafe hs_botan_cipher_output_size :: BotanStructT -> Int -> IO Int ++foreign import ccall unsafe botan_stream_cipher_init :: MBA## BotanStructT -> BA## Word8 -> IO CInt+foreign import ccall unsafe "&botan_stream_cipher_destroy"+    botan_stream_cipher_destroy :: FunPtr (BotanStructT -> IO ())+foreign import ccall unsafe botan_stream_cipher_seek :: BotanStructT -> CSize -> IO CInt++foreign import ccall unsafe botan_stream_cipher_clear :: BotanStructT -> IO CInt+foreign import ccall unsafe botan_stream_cipher_get_keyspec :: BotanStructT+                                                     -> MBA## CSize   -- ^ minimum_keylength+                                                     -> MBA## CSize   -- ^ maximum_keylength+                                                     -> MBA## CSize   -- ^ keylength_modulo+                                                     -> IO CInt+foreign import ccall unsafe botan_stream_cipher_set_key :: BotanStructT -> Ptr Word8 -> CSize -> IO CInt+foreign import ccall unsafe hs_botan_stream_cipher_set_iv+    :: BotanStructT -> BA## Word8 -> Int -> Int -> IO CInt+foreign import ccall unsafe hs_botan_stream_cipher_cipher+    :: BotanStructT+    -> MBA## Word8  -- ^ output+    -> BA## Word8   -- ^ input+    -> Int          -- ^ input offset+    -> Int          -- ^ input len+    -> IO CInt      ++foreign import ccall unsafe botan_stream_cipher_write_keystream+    :: BotanStructT+    -> MBA## Word8  -- ^ output+    -> CSize        -- ^ output size+    -> IO CInt      ++foreign import ccall unsafe botan_stream_cipher_valid_iv_length :: BotanStructT -> CSize -> IO CInt+foreign import ccall unsafe botan_stream_cipher_get_default_iv_length :: BotanStructT -> MBA## Int -> IO CInt+ -------------------------------------------------------------------------------- -- PBKDF  foreign import ccall unsafe hs_botan_pwdhash :: BA## Word8                                              -> Int -> Int -> Int-                                             -> MBA## Word8 -> Int              -- ^ output+                                             -> Ptr Word8 -> Int                -- ^ output                                              -> BA## Word8 -> Int               -- ^ passphrase                                              -> BA## Word8 -> Int -> Int        -- ^ salt                                              -> IO CInt  foreign import ccall unsafe hs_botan_pwdhash_timed :: BA## Word8                                                    -> Int-                                                   -> MBA## Word8 -> Int        -- ^ output+                                                   -> Ptr Word8 -> Int          -- ^ output                                                    -> BA## Word8 -> Int         -- ^ passphrase                                                    -> BA## Word8 -> Int -> Int  -- ^ salt                                                    -> IO CInt@@ -249,8 +274,8 @@ -- KDF  foreign import ccall unsafe hs_botan_kdf :: BA## Word8-                                         -> MBA## Word8 -> Int-                                         -> BA## Word8 -> Int -> Int+                                         -> Ptr Word8 -> CSize+                                         -> Ptr Word8 -> CSize                                          -> BA## Word8 -> Int -> Int                                          -> BA## Word8 -> Int -> Int                                          -> IO CInt@@ -259,14 +284,14 @@ -------------------------------------------------------------------------------- -- Password Hashing -foreign import ccall unsafe hs_botan_bcrypt_generate :: MBA## Word8-                                                     -> BA## Word8 -> Int -> Int-                                                     -> BotanStructT-                                                     -> Int-                                                     -> Word32-                                                     -> IO Int+foreign import ccall unsafe botan_bcrypt_generate :: MBA## Word8 -> MBA## CSize+                                                  -> BA## Word8+                                                  -> BotanStructT+                                                  -> Int+                                                  -> Word32+                                                  -> IO CInt -foreign import ccall unsafe hs_botan_bcrypt_is_valid :: BA## Word8 -> Int -> Int+foreign import ccall unsafe hs_botan_bcrypt_is_valid :: BA## Word8                                                       -> BA## Word8 -> Int -> Int                                                      -> IO CInt @@ -280,7 +305,7 @@  foreign import ccall unsafe botan_mac_final :: BotanStructT -> MBA## Word8 -> IO CInt -foreign import ccall unsafe hs_botan_mac_set_key :: BotanStructT -> BA## Word8 -> Int -> Int -> IO CInt+foreign import ccall unsafe botan_mac_set_key :: BotanStructT -> Ptr Word8 -> CSize -> IO CInt  foreign import ccall unsafe hs_botan_mac_update :: BotanStructT -> BA## Word8 -> Int -> Int-> IO CInt @@ -428,7 +453,7 @@  foreign import ccall unsafe hs_botan_pk_op_encrypt :: BotanStructT                                                    -> BotanStructT-                                                   -> MBA## Word8 -> MBA## Int+                                                   -> MBA## Word8 -> MBA## CSize                                                    -> BA## Word8 -> Int -> Int                                                    -> IO CInt @@ -446,7 +471,7 @@                                                               -> IO CInt  foreign import ccall unsafe hs_botan_pk_op_decrypt :: BotanStructT-                                                   -> MBA## Word8 -> MBA## Int+                                                   -> MBA## Word8 -> MBA## CSize                                                    -> BA## Word8 -> Int -> Int                                                    -> IO CInt @@ -470,7 +495,7 @@ foreign import ccall unsafe botan_pk_op_sign_finish :: BotanStructT                                                     -> BotanStructT                                                     -> MBA## Word8-                                                    -> MBA## Int+                                                    -> MBA## CSize                                                     -> IO CInt  foreign import ccall unsafe "&botan_pk_op_sign_destroy" botan_pk_op_sign_destroy :: FunPtr (BotanStructT -> IO ())@@ -506,7 +531,7 @@ foreign import ccall unsafe "&botan_pk_op_key_agreement_destroy" botan_pk_op_key_agreement_destroy :: FunPtr (BotanStructT -> IO ())  foreign import ccall unsafe botan_pk_op_key_agreement_export_public :: BotanStructT-                                                                    -> MBA## Word8 -> MBA## Int+                                                                    -> MBA## Word8 -> MBA## CSize                                                                     -> IO CInt  foreign import ccall unsafe botan_pk_op_key_agreement_size :: BotanStructT@@ -514,7 +539,7 @@                                                            -> IO CInt  foreign import ccall unsafe hs_botan_pk_op_key_agreement :: BotanStructT-                                                         -> MBA## Word8 -> MBA## Int+                                                         -> Ptr Word8 -> CSize                                                          -> BA## Word8 -> Int -> Int                                                          -> BA## Word8 -> Int -> Int                                                          -> IO CInt@@ -524,14 +549,14 @@                                                     -> BA## Word8                                                     -> BA## Word8 -> Int -> Int                                                     -> BA## Word8 -> Int -> Int-                                                    -> MBA## Word8 -> MBA## Int+                                                    -> MBA## Word8 -> MBA## CSize                                                     -> IO CInt  foreign import ccall unsafe hs_botan_mceies_decrypt :: BotanStructT                                                     -> BA## Word8                                                     -> BA## Word8 -> Int -> Int                                                     -> BA## Word8 -> Int -> Int-                                                    -> MBA## Word8 -> MBA## Int+                                                    -> MBA## Word8 -> MBA## CSize                                                     -> IO CInt -} @@ -676,14 +701,14 @@ -------------------------------------------------------------------------------- -- Advanced Encryption Standard (AES) Key Wrap Algorithm -foreign import ccall unsafe hs_botan_key_wrap3394 :: BA## Word8 -> Int -> Int-                                                  -> BA## Word8 -> Int -> Int+foreign import ccall unsafe botan_key_wrap3394 :: Ptr Word8 -> CSize+                                                  -> Ptr Word8 -> CSize                                                   -> MBA## Word8 -> MBA## CSize                                                   -> IO CInt  foreign import ccall unsafe hs_botan_key_unwrap3394 :: BA## Word8 -> Int -> Int-                                                    -> BA## Word8 -> Int -> Int-                                                    -> MBA## Word8 -> MBA## CSize+                                                    -> Ptr Word8 -> CSize+                                                    -> Ptr Word8 -> CSize                                                     -> IO CInt  --------------------------------------------------------------------------------
Z/Crypto/Cipher.hs view
@@ -20,27 +20,30 @@   , BlockCipher, blockCipherName, blockCipherKeySpec, blockCipherSize   , newBlockCipher, setBlockCipherKey, clearBlockCipher   , encryptBlocks, decryptBlocks-    -- * Stream Cipher & Cipher Mode-  , StreamCipherType(..), newStreamCipher+    -- * Cipher Mode   , CipherMode(..), CipherDirection(..)-  , Cipher, cipherName, cipherUpdateGranularity-  , cipherKeySpec, cipherTagLength, defaultNonceLength-  , newCipher-    -- * Cipher operations-  , setCipherKey, clearCipher, resetCipher, setAssociatedData-  , startCipher, updateCipher, finishCipher, cipherBIO+  , Cipher, cipherName, cipherKeySpec, cipherTagLength, defaultNonceLength+  , newCipher, setCipherKey, clearCipher, runCipher+    -- * Stream Cipher+  , StreamCipherType(..), StreamCipher, streamCipherName, streamCipherKeySpec, defaultIVLength+  , newStreamCipher, setStreamCipherKey, clearStreamCipher+  , setStreamCipherIV, seekStreamCipher, runStreamCipher, streamCipherKeyStream, streamCipherBIO, keyStreamSource     -- * Internal helps   , blockCipherTypeToCBytes   , withBlockCipher   , withCipher+  , withStreamCipher+    -- * re-export+  , HashType(..)+  , module Z.Crypto.SafeMem   ) where  import           Control.Monad-import           Data.IORef import           GHC.Generics import           Z.Botan.Exception import           Z.Botan.FFI import           Z.Crypto.Hash+import           Z.Crypto.SafeMem import           Z.Data.CBytes       as CB import           Z.Data.JSON         (JSON) import qualified Z.Data.Text         as T@@ -268,13 +271,12 @@  -- | Set the cipher key, which is required before encrypting or decrypting. ---setBlockCipherKey :: HasCallStack => BlockCipher -> V.Bytes -> IO ()+setBlockCipherKey :: HasCallStack => BlockCipher -> Secret -> IO () {-# INLINABLE setBlockCipherKey #-} setBlockCipherKey (BlockCipher bc _ _ _) key =     withBotanStruct bc $ \ pbc -> do-        withPrimVectorUnsafe key $ \ pkey key_off key_len -> do-            throwBotanIfMinus_ (hs_botan_block_cipher_set_key-                pbc pkey key_off key_len)+        withSecret key $ \ pkey key_len ->+            throwBotanIfMinus_ (botan_block_cipher_set_key pbc pkey key_len)  -- | Clear the internal state (such as keys) of this cipher object. clearBlockCipher :: HasCallStack => BlockCipher -> IO ()@@ -320,81 +322,7 @@                 throwBotanIfMinus_ (hs_botan_block_cipher_decrypt_blocks                     pbc pb pboff pbuf n)) --------------------------------------------------------------------------------- --- | In contrast to block ciphers, stream ciphers operate on a plaintext stream instead of blocks. Thus encrypting data results in changing the internal state of the cipher and encryption of plaintext with arbitrary length is possible in one go (in byte amounts).-data StreamCipherType-      -- | A cipher mode that converts a block cipher into a stream cipher.-      --  It offers parallel execution and can seek within the output stream, both useful properties.-    = CTR_BE BlockCipherType-      -- | Another stream cipher based on a block cipher.-      -- Unlike CTR mode, it does not allow parallel execution or seeking within the output stream. Prefer CTR.-    | OFB BlockCipherType-      -- | A very fast cipher, now widely deployed in TLS as part of the ChaCha20Poly1305 AEAD.-      -- Can be used with 8 (fast but dangerous), 12 (balance), or 20 rounds (conservative).-      -- Even with 20 rounds, ChaCha is very fast. Use 20 rounds.-    | ChaCha8-    | ChaCha12-    | ChaCha20-      -- | An earlier iteration of the ChaCha design,-      -- this cipher is popular due to its use in the libsodium library. Prefer ChaCha.-    | Salsa20-      -- | This is the SHAKE-128 XOF exposed as a stream cipher.-      -- It is slower than ChaCha and somewhat obscure.-      -- It does not support IVs or seeking within the cipher stream.-    | SHAKE128'-      -- | An old and very widely deployed stream cipher notable for its simplicity.-      -- It does not support IVs or seeking within the cipher stream.-      -- Warning: RC4 is now badly broken. Avoid in new code and use only if-      -- required for compatibility with existing systems.-    | RC4-  deriving (Show, Read, Eq, Ord, Generic)-  deriving anyclass (T.Print, JSON)--streamCipherTypeToCBytes :: StreamCipherType -> CBytes-{-# INLINABLE streamCipherTypeToCBytes #-}-streamCipherTypeToCBytes s = case s of-    CTR_BE b  -> CB.concat ["CTR-BE(", blockCipherTypeToCBytes b, ")"]-    OFB b     -> CB.concat ["OFB(", blockCipherTypeToCBytes b, ")"]-    ChaCha8   -> "ChaCha(8)"-    ChaCha12  -> "ChaCha(12)"-    ChaCha20  -> "ChaCha(20)"-    Salsa20   -> "Salsa20"-    SHAKE128' ->  "SHAKE-128"-    RC4       -> "RC4"---- | Create a new stream cipher.----newStreamCipher :: HasCallStack => StreamCipherType -> CipherDirection -> IO Cipher-{-# INLINABLE newStreamCipher #-}-newStreamCipher typ dir = do-    let name = streamCipherTypeToCBytes typ-    ci <- newBotanStruct-        (\ bts -> withCBytesUnsafe name $ \ pb ->-            botan_cipher_init bts pb (cipherDirectionToFlag dir))-        botan_cipher_destroy--    withBotanStruct ci $ \ pci -> do-        (g, _) <- allocPrimUnsafe $ \ pg ->-            botan_cipher_get_update_granularity pci pg--        (a, (b, (c, _))) <- allocPrimUnsafe $ \ pa ->-            allocPrimUnsafe $ \ pb ->-                allocPrimUnsafe $ \ pc ->-                    throwBotanIfMinus_-                        (botan_cipher_get_keyspec pci pa pb pc)--        (t, _) <- allocPrimUnsafe $ \ pt ->-            botan_cipher_get_tag_length pci pt--        (f, _) <- allocPrimUnsafe $ \ pt ->-            botan_cipher_get_minimum_final_size pci pt--        (n, _) <- allocPrimUnsafe $ \ pn ->-            botan_cipher_get_default_nonce_length pci pn--        return (Cipher ci name g (KeySpec a b c) t f n)- -------------------------------------------------------------------------------- -- @@ -436,17 +364,32 @@     --     -- NIST standard, commonly used. Requires a 128-bit block cipher.     -- Fairly slow, unless hardware support for carryless multiplies is available.+    --+    -- Default tag size is 16     | GCM BlockCipherType+    -- | GCM with custom tag length+    | GCM' BlockCipherType Int         -- ^ tag size+     -- | OCB     --     -- A block cipher based AEAD. Supports 128-bit, 256-bit and 512-bit block ciphers.     -- This mode is very fast and easily secured against side channels.     -- Adoption has been poor because it is patented in the United States,     -- though a license is available allowing it to be freely used by open source software.+    --+    -- Default tag size is 16     | OCB BlockCipherType+    -- | OCB with custom tag length+    | OCB' BlockCipherType Int         -- ^ tag size+     -- | EAX     -- A secure composition of CTR mode and CMAC. Supports 128-bit, 256-bit and 512-bit block ciphers.+    --+    -- Default tag size is the block size     | EAX BlockCipherType+    -- | EAX with custom tag length+    | EAX' BlockCipherType Int         -- ^ tag size+     -- | SIV     --     -- Requires a 128-bit block cipher. Unlike other AEADs, SIV is “misuse resistant”;@@ -460,13 +403,26 @@     --     -- A composition of CTR mode and CBC-MAC. Requires a 128-bit block cipher.     -- This is a NIST standard mode, but that is about all to recommend it. Prefer EAX.+    --+    -- Default tag size is 16 and L is 3     | CCM BlockCipherType+    -- | CCM with custom tag size+    | CCM' BlockCipherType+            Int         -- ^ tag size+            Int         -- ^ L+     -- | CFB     --     -- CFB uses a block cipher to create a self-synchronizing stream cipher.     -- It is used for example in the OpenPGP protocol. There is no reason to prefer it,     -- as it has worse performance characteristics than modes such as CTR or CBC.-    | CFB BlockCipherType Int+    --+    -- The default feedback bits size are 8*blocksize+    | CFB BlockCipherType+    -- | CFB with custom feedback bits size+    | CFB' BlockCipherType+            Int     -- ^ feedback bits size+     -- | XTS     --     -- XTS is a mode specialized for encrypting disk or database storage where ciphertext expansion@@ -514,13 +470,41 @@ {-# INLINABLE cipherTypeToCBytes #-} cipherTypeToCBytes ct = case ct of     ChaCha20Poly1305 -> "ChaCha20Poly1305"-    GCM        bct -> blockCipherTypeToCBytes bct <> "/GCM"-    OCB        bct -> blockCipherTypeToCBytes bct <> "/OCB"-    EAX        bct -> blockCipherTypeToCBytes bct <> "/EAX"+    GCM        bct        -> blockCipherTypeToCBytes bct <> "/GCM"+    GCM'       bct tagsiz -> CB.concat [ blockCipherTypeToCBytes bct+                                     , "/GCM("+                                     , CB.fromText (T.toText tagsiz)+                                     , ")"+                                     ]++    OCB        bct        -> blockCipherTypeToCBytes bct <> "/OCB"+    OCB'       bct tagsiz -> CB.concat [ blockCipherTypeToCBytes bct+                                     , "/OCB("+                                     , CB.fromText (T.toText tagsiz)+                                     , ")"+                                     ]++    EAX        bct        -> blockCipherTypeToCBytes bct <> "/EAX"+    EAX'       bct tagsiz -> CB.concat [ blockCipherTypeToCBytes bct+                                     , "/EAX("+                                     , CB.fromText (T.toText tagsiz)+                                     , ")"+                                     ]++     SIV        bct -> blockCipherTypeToCBytes bct <> "/SIV"-    CCM        bct -> blockCipherTypeToCBytes bct <> "/CCM"-    CFB           bct 0 -> blockCipherTypeToCBytes bct <> "/CFB"-    CFB           bct x -> CB.concat [ blockCipherTypeToCBytes bct++    CCM        bct          -> blockCipherTypeToCBytes bct <> "/CCM"+    CCM'       bct tagsiz l -> CB.concat [ blockCipherTypeToCBytes bct+                                         , "/CCM("+                                         , CB.fromText (T.toText tagsiz)+                                         , ","+                                         , CB.fromText (T.toText l)+                                         , ")"+                                         ]++    CFB           bct   -> blockCipherTypeToCBytes bct <> "/CFB"+    CFB'          bct x -> CB.concat [ blockCipherTypeToCBytes bct                                      , "/CFB("                                      , CB.fromText (T.toText x)                                      , ")"@@ -537,11 +521,8 @@ data Cipher = Cipher     { cipher                  :: {-# UNPACK #-} !BotanStruct     , cipherName              :: {-# UNPACK #-} !CBytes        -- ^ cipher algo name-    , cipherUpdateGranularity :: {-# UNPACK #-} !Int           -- ^ cipher input chunk granularity     , cipherKeySpec           :: {-# UNPACK #-} !KeySpec       -- ^ cipher keyspec-    , cipherTagLength         :: {-# UNPACK #-} !Int    -- ^ AEAD tag length,-                                                        -- will be zero for non-authenticated ciphers.-    , cipherMinFinalSize      :: {-# UNPACK #-} !Int    -- ^ Minimum input size for final chunk.+    , cipherTagLength         :: {-# UNPACK #-} !Int           -- ^ AEAD tag length, will be 0 for non-authenticated ciphers.     , defaultNonceLength      :: {-# UNPACK #-} !Int    -- ^ a proper default nonce length.     }     deriving (Show, Generic)@@ -550,7 +531,7 @@ -- | Pass 'Cipher' to FFI as 'botan_cipher_t'. withCipher :: Cipher -> (BotanStructT -> IO r) -> IO r {-# INLINABLE withCipher #-}-withCipher (Cipher c _ _ _ _ _ _) = withBotanStruct c+withCipher (Cipher c _ _ _ _) = withBotanStruct c  -- | Create a new cipher. --@@ -564,8 +545,6 @@         botan_cipher_destroy      withBotanStruct ci $ \ pci -> do-        (g, _) <- allocPrimUnsafe $ \ pg ->-            botan_cipher_get_update_granularity pci pg          (a, (b, (c, _))) <- allocPrimUnsafe $ \ pa ->             allocPrimUnsafe $ \ pb ->@@ -576,144 +555,237 @@         (t, _) <- allocPrimUnsafe $ \ pt ->             botan_cipher_get_tag_length pci pt -        (f, _) <- allocPrimUnsafe $ \ pt ->-            botan_cipher_get_minimum_final_size pci pt-         (n, _) <- allocPrimUnsafe $ \ pn ->             botan_cipher_get_default_nonce_length pci pn -        return (Cipher ci name g (KeySpec a b c) t f n)+        return (Cipher ci name (KeySpec a b c) t n)  -- | Clear the internal state (such as keys) of this cipher object. -- clearCipher :: HasCallStack => Cipher -> IO () {-# INLINABLE clearCipher #-}-clearCipher ci =-    withCipher ci (throwBotanIfMinus_ . botan_cipher_clear)---- | Reset the message specific state for this cipher.--- Without resetting the keys, this resets the nonce, and any state--- associated with any message bits that have been processed so far.------ It is conceptually equivalent to calling botan_cipher_clear followed--- by botan_cipher_set_key with the original key.----resetCipher :: HasCallStack => Cipher -> IO ()-{-# INLINABLE resetCipher #-}-resetCipher ci =-    withCipher ci (throwBotanIfMinus_ . botan_cipher_reset)+clearCipher ci = withCipher ci (throwBotanIfMinus_ . botan_cipher_clear)  -- | Set the key for this cipher object ---setCipherKey :: HasCallStack => Cipher -> V.Bytes -> IO ()+setCipherKey :: HasCallStack => Cipher -> Secret -> IO () {-# INLINABLE setCipherKey #-} setCipherKey ci key =     withCipher ci $ \ pci -> do-        withPrimVectorUnsafe key $ \ pkey key_off key_len -> do-            throwBotanIfMinus_ (hs_botan_cipher_set_key-                pci pkey key_off key_len)+        withSecret key $ \ pkey key_len -> do+            throwBotanIfMinus_ (botan_cipher_set_key pci pkey key_len) --- | Set the associated data. Will fail if cipher is not an AEAD.+-- | Do the encryption or decryption. ---setAssociatedData :: HasCallStack => Cipher -> V.Bytes -> IO ()-{-# INLINABLE setAssociatedData #-}-setAssociatedData ci ad =+-- BE CAREFUL ON 'Nonce' handling! Some 'CipherMode's will fail if 'Nonce' is reused or not randomly enough.+runCipher :: HasCallStack+          => Cipher+          -> Nonce         -- ^ nonce+          -> V.Bytes       -- ^ input+          -> V.Bytes       -- ^ associated data, ignored if not an AEAD or empty+          -> IO V.Bytes+{-# INLINABLE runCipher #-}+runCipher ci nonce inp ad =     withCipher ci $ \ pci -> do-        withPrimVectorUnsafe ad $ \ pad ad_off ad_len -> do++        when (cipherTagLength ci /= 0) . withPrimVectorUnsafe ad $ \ pad ad_off ad_len -> do             throwBotanIfMinus_ (hs_botan_cipher_set_associated_data                 pci pad ad_off ad_len) --- | Begin processing a new message using the provided nonce.+        withPrimVectorUnsafe nonce $ \ pnonce nonce_off nonce_len ->+            throwBotanIfMinus_ (hs_botan_cipher_start pci pnonce nonce_off nonce_len)++        osiz <- hs_botan_cipher_output_size pci (V.length inp)++        (out, r) <- allocPrimVectorUnsafe osiz $ \ out ->+            withPrimVectorUnsafe inp $ \ pinp inp_off inp_len ->+                throwBotanIfMinus (hs_botan_cipher_finish pci out osiz pinp inp_off inp_len)++        return $! V.unsafeTake r out++--------------------------------------------------------------------------------++-- | In contrast to block ciphers, stream ciphers operate on a plaintext stream instead of blocks. Thus encrypting data results in changing the internal state of the cipher and encryption of plaintext with arbitrary length is possible in one go (in byte amounts).+data StreamCipherType+      -- | A cipher mode that converts a block cipher into a stream cipher.+      --  It offers parallel execution and can seek within the output stream, both useful properties.+    = CTR_BE BlockCipherType+      -- | Another stream cipher based on a block cipher.+      -- Unlike CTR mode, it does not allow parallel execution or seeking within the output stream. Prefer CTR.+    | OFB BlockCipherType+      -- | A very fast cipher, now widely deployed in TLS as part of the ChaCha20Poly1305 AEAD.+      -- Can be used with 8 (fast but dangerous), 12 (balance), or 20 rounds (conservative).+      -- Even with 20 rounds, ChaCha is very fast. Use 20 rounds.+    | ChaCha8+    | ChaCha12+    | ChaCha20+      -- | An earlier iteration of the ChaCha design,+      -- this cipher is popular due to its use in the libsodium library. Prefer ChaCha.+    | Salsa20+      -- | This is the SHAKE-128 XOF exposed as a stream cipher.+      -- It is slower than ChaCha and somewhat obscure.+      -- It does not support IVs or seeking within the cipher stream.+    | SHAKE128'+      -- | An old and very widely deployed stream cipher notable for its simplicity.+      -- It does not support IVs or seeking within the cipher stream.+      -- Warning: RC4 is now badly broken. Avoid in new code and use only if+      -- required for compatibility with existing systems.+    | RC4+  deriving (Show, Read, Eq, Ord, Generic)+  deriving anyclass (T.Print, JSON)++-- | A Botan stream cipher.+data StreamCipher = StreamCipher+    { streamCipher                  :: {-# UNPACK #-} !BotanStruct+    , streamCipherName              :: {-# UNPACK #-} !CBytes        -- ^ cipher algo name+    , streamCipherKeySpec           :: {-# UNPACK #-} !KeySpec       -- ^ cipher keyspec+    , defaultIVLength               :: {-# UNPACK #-} !Int           -- ^ a proper default IV length.+    }+    deriving (Show, Generic)+    deriving anyclass T.Print++withStreamCipher :: StreamCipher -> (BotanStructT -> IO r) -> IO r+{-# INLINE withStreamCipher #-}+withStreamCipher (StreamCipher sci _ _ _) = withBotanStruct sci++streamCipherTypeToCBytes :: StreamCipherType -> CBytes+{-# INLINABLE streamCipherTypeToCBytes #-}+streamCipherTypeToCBytes s = case s of+    CTR_BE b  -> CB.concat ["CTR-BE(", blockCipherTypeToCBytes b, ")"]+    OFB b     -> CB.concat ["OFB(", blockCipherTypeToCBytes b, ")"]+    ChaCha8   -> "ChaCha(8)"+    ChaCha12  -> "ChaCha(12)"+    ChaCha20  -> "ChaCha(20)"+    Salsa20   -> "Salsa20"+    SHAKE128' ->  "SHAKE-128"+    RC4       -> "RC4"++-- | Create a new stream cipher. ---startCipher :: HasCallStack-            => Cipher-            -> V.Bytes      -- ^ nonce-            -> IO ()-{-# INLINABLE startCipher #-}-startCipher ci nonce =-    withCipher ci $ \ pci -> do-        withPrimVectorUnsafe nonce $ \ pnonce nonce_off nonce_len -> do-            throwBotanIfMinus_ (hs_botan_cipher_start-                pci pnonce nonce_off nonce_len)+-- A stream cipher is a symmetric key cipher where plaintext digits are combined with a pseudorandom cipher digit stream (keystream).+-- In a stream cipher, each plaintext digit is encrypted one at a time with the corresponding digit of the keystream, to give a digit of the ciphertext stream.+-- Since encryption of each digit is dependent on the current state of the cipher, it is also known as state cipher.+-- In practice, a digit is typically a bit and the combining operation is an exclusive-or (XOR).+--+newStreamCipher :: HasCallStack => StreamCipherType -> IO StreamCipher+{-# INLINABLE newStreamCipher #-}+newStreamCipher typ = do+    let name = streamCipherTypeToCBytes typ+    ci <- newBotanStruct+        (\ bts -> withCBytesUnsafe name (botan_stream_cipher_init bts))+        botan_stream_cipher_destroy +    withBotanStruct ci $ \ pci -> do++        (a, (b, (c, _))) <- allocPrimUnsafe $ \ pa ->+            allocPrimUnsafe $ \ pb ->+                allocPrimUnsafe $ \ pc ->+                    throwBotanIfMinus_+                        (botan_stream_cipher_get_keyspec pci pa pb pc)++        (n, _) <- allocPrimUnsafe $ \ pn ->+            botan_stream_cipher_get_default_iv_length pci pn++        return (StreamCipher ci name (KeySpec a b c) n)++-- | Set the key for the 'StreamCipher' object+--+setStreamCipherKey :: HasCallStack => StreamCipher -> Secret -> IO ()+{-# INLINABLE setStreamCipherKey #-}+setStreamCipherKey ci key =+    withStreamCipher ci $ \ pci ->+    withSecret key $ \ pkey key_len ->+        throwBotanIfMinus_ (botan_stream_cipher_set_key pci pkey key_len)++-- | Set the initail vector for a 'StreamCipher'.+setStreamCipherIV :: StreamCipher -> Nonce -> IO ()+{-# INLINABLE setStreamCipherIV #-}+setStreamCipherIV sc nonce =+    withStreamCipher sc $ \ psc ->+    withPrimVectorUnsafe nonce $ \ n noff nlen ->+        throwBotanIfMinus_ $ hs_botan_stream_cipher_set_iv psc n noff nlen++-- | Clear the internal state (such as keys) of this cipher object.+--+clearStreamCipher :: HasCallStack => StreamCipher -> IO ()+{-# INLINABLE clearStreamCipher #-}+clearStreamCipher ci = withStreamCipher ci (throwBotanIfMinus_ . botan_stream_cipher_clear)++-- | Seek 'StreamCipher' 's state to given offset.+seekStreamCipher :: StreamCipher -> Int -> IO ()+{-# INLINABLE seekStreamCipher #-}+seekStreamCipher sc off =+    withStreamCipher sc $ \ psc ->+        throwBotanIfMinus_ $ botan_stream_cipher_seek psc (fromIntegral off)+ -- | Update cipher with some data. ----- If the input size is not a multiplier of 'cipherUpdateGranularity', there'll--- be some trailing input.-updateCipher :: HasCallStack-             => Cipher-             -> V.Bytes-             -> IO (V.Bytes, V.Bytes)   -- ^ trailing input, output-{-# INLINABLE updateCipher #-}-updateCipher ci input =-    withCipher ci $ \ pci -> do+-- Since stream ciphers work by XOR data, encryption and decryption are the same process.+runStreamCipher :: HasCallStack+                   => StreamCipher+                   -> V.Bytes+                   -> IO V.Bytes        -- ^ trailing input, output+{-# INLINABLE runStreamCipher #-}+runStreamCipher sci input =+    withStreamCipher sci $ \ pci -> do         withPrimVectorUnsafe input $ \ in_p in_off in_len -> do-            (out, r) <- allocPrimVectorUnsafe in_len $ \ out_p ->-                throwBotanIfMinus (hs_botan_cipher_update pci+            (out, _) <- allocPrimVectorUnsafe in_len $ \ out_p ->+                throwBotanIfMinus (hs_botan_stream_cipher_cipher pci                     out_p in_p in_off in_len)-            return (V.unsafeDrop r input, V.unsafeTake r out)+            return out --- | Finish cipher with some data.+-- | Export 'StreamCipher' 's key stream for other usage. ----- You can directly call this function to encrypt a whole message,--- Note some cipher modes have a minimal input length requirement for last chunk(CTS, XTS, etc.).-finishCipher :: HasCallStack-             => Cipher-             -> V.Bytes-             -> IO V.Bytes-{-# INLINABLE finishCipher #-}-finishCipher (Cipher ci _ ug _ tag_len _ _) input =-    withBotanStruct ci $ \ pci -> do-        withPrimVectorUnsafe input $ \ in_p in_off in_len -> do-            let !out_len = in_len + ug + tag_len-            (pa, r) <- allocPrimArrayUnsafe out_len $ \ out_p -> do-                throwBotanIfMinus (hs_botan_cipher_finish pci-                    out_p out_len in_p in_off in_len)-            mpa <- unsafeThawPrimArray pa-            shrinkMutablePrimArray mpa r-            pa' <- unsafeFreezePrimArray mpa-            return (V.PrimVector pa' 0 r)+streamCipherKeyStream :: HasCallStack+                      => StreamCipher+                      -> Int+                      -> IO V.Bytes+{-# INLINABLE streamCipherKeyStream #-}+streamCipherKeyStream sci siz =+    withStreamCipher sci $ \ pci -> do+        (pa, _) <- allocPrimVectorUnsafe siz $ \ out_p -> do+            throwBotanIfMinus (botan_stream_cipher_write_keystream pci out_p (fromIntegral siz))+        return pa --- | Wrap a cipher into a 'BIO' node(experimental).+-- | Wrap a 'StreamCipher' into a 'BIO' node(experimental). ----- The cipher should have already started by setting key, nounce, etc,--- for example to encrypt a file in constant memory:+-- The cipher should have already started by setting key, iv, etc,+-- for example to encrypt a file in constant memory using AES with CTR mode: -- -- @--- encryptFile :: CBytes -> CBytes -> IO ()--- encryptFile origin target = do+-- import Z.Data.CBytes (CBytes)+-- import Z.IO.BIO+-- import Z.IO+-- import Z.Crypto.Cipher+--+-- -- | encryption and decryption are the same process.+-- cipherFile :: CBytes -> CBytes -> IO ()+-- cipherFile origin target = do --     let demoKey = "12345678123456781234567812345678"---         nonce = "demo only, use random nonce"---     cipher <- newCipher (EAX AES256) CipherEncrypt---     setCipherKey cipher demoKey---     startCipher cipher nonce---     encryptor <- cipherBIO cipher+--         iv = "demo only !!!!!!"+--     cipher <- newStreamCipher (CTR_BE AES256)+--     setStreamCipherKey cipher demoKey+--     setStreamCipherIV cipher iv -----     withResource (initSourceFromFile origin) $ \ src ->---         withResource (initSinkToFile target) $ \ sink ->---             runBIO_ $ src . encryptor . sink+--     withResource (initSourceFromFile origin) $ \\ src ->+--         withResource (initSinkToFile target) $ \\ sink ->+--             runBIO_ $ src . streamCipherBIO cipher . sink -- @ -- -- Note that many cipher modes have a maximum length limit on the plaintext under a security context, -- i.e. a key nonce combination. If you want to encrypt a large message, please consider divide it into -- smaller chunks, and re-key or change the iv.-cipherBIO :: HasCallStack => Cipher -> IO (BIO V.Bytes V.Bytes)-{-# INLINABLE cipherBIO #-}-cipherBIO c = do-    trailingRef <- newIORef V.empty-    return $ \ k mbs -> case mbs of-        Just chunk -> do-            trailing <- readIORef trailingRef-            if (V.length trailing >= cipherUpdateGranularity c)-                && (V.length chunk >= cipherMinFinalSize c)-            then do-                (rest, out) <- updateCipher c trailing-                k (Just out)-                writeIORef trailingRef (rest `V.append` chunk)-            else writeIORef trailingRef (trailing `V.append` chunk)-        _ -> do-            trailing <- readIORef trailingRef-            bs <- finishCipher c trailing-            if V.null bs-            then k EOF-            else k (Just bs) >> k EOF+streamCipherBIO :: HasCallStack => StreamCipher -> BIO V.Bytes V.Bytes+{-# INLINABLE streamCipherBIO #-}+streamCipherBIO c = \ k mbs -> case mbs of+    Just chunk -> k . Just =<< runStreamCipher c chunk+    _ -> k EOF++-- | Turn a 'StreamCipher' into a key stream source.+--+keyStreamSource :: HasCallStack+                => StreamCipher+                -> Int              -- ^ each chunk size+                -> Source V.Bytes+{-# INLINABLE keyStreamSource #-}+keyStreamSource c cs = \ k _ -> k . Just =<< streamCipherKeyStream c cs
Z/Crypto/Hash.hs view
@@ -29,12 +29,15 @@   -- * Internal helper   , hashTypeToCBytes   , withHash+    -- * re-export+  , module Z.Crypto.SafeMem   ) where  import           GHC.Generics      (Generic) import           System.IO.Unsafe  (unsafePerformIO) import           Z.Botan.Exception (HasCallStack, throwBotanIfMinus_) import           Z.Botan.FFI+import           Z.Crypto.SafeMem import           Z.Data.CBytes     as CB import           Z.Data.JSON       (JSON) import qualified Z.Data.Text       as T@@ -221,11 +224,11 @@             throwBotanIfMinus_ (hs_botan_hash_update pbts pbs off len)  -- | Compute hash value.-finalHash :: HasCallStack => Hash -> IO V.Bytes+finalHash :: HasCallStack => Hash -> IO CEBytes {-# INLINABLE finalHash #-} finalHash (Hash bts _ siz) =     withBotanStruct bts $ \ pbts -> do-        fst <$> allocPrimVectorUnsafe siz (\ pout ->+        newCEBytesUnsafe siz (\ pout ->             throwBotanIfMinus_ (botan_hash_final pbts pout))  {-| Trun 'Hash' to a 'V.Bytes' sink, update 'Hash' by write bytes to the sink.@@ -255,7 +258,7 @@     _       -> k EOF  -- | Directly compute a message's hash.-hash :: HasCallStack => HashType -> V.Bytes -> V.Bytes+hash :: HasCallStack => HashType -> V.Bytes -> CEBytes {-# INLINABLE hash #-} hash ht inp = unsafePerformIO $ do     h <- newHash ht@@ -263,7 +266,7 @@     finalHash h  -- | Directly compute a chunked message's hash.-hashChunks:: HasCallStack => HashType -> [V.Bytes] -> V.Bytes+hashChunks:: HasCallStack => HashType -> [V.Bytes] -> CEBytes {-# INLINABLE hashChunks #-} hashChunks ht inp = unsafePerformIO $ do     h <- newHash ht
Z/Crypto/KDF.hs view
@@ -25,6 +25,8 @@   -- * Internal helps   , kdfTypeToCBytes   , pbkdfTypeToParam+    -- * re-export+  , module Z.Crypto.SafeMem   ) where  import           GHC.Generics@@ -32,6 +34,7 @@ import           Z.Botan.FFI import           Z.Crypto.Hash     (HashType (..), hashTypeToCBytes) import           Z.Crypto.MAC      (MACType (..), macTypeToCBytes)+import           Z.Crypto.SafeMem import           Z.Data.CBytes     (CBytes, withCBytes, withCBytesUnsafe) import qualified Z.Data.CBytes     as CB import           Z.Data.JSON       (JSON)@@ -96,22 +99,22 @@ kdf :: HasCallStack     => KDFType    -- ^ the name of the given PBKDF algorithm     -> Int        -- ^ length of output key-    -> V.Bytes    -- ^ secret+    -> Secret     -- ^ secret     -> V.Bytes    -- ^ salt     -> V.Bytes    -- ^ label-    -> IO V.Bytes+    -> IO Secret {-# INLINABLE kdf #-} kdf algo siz secret salt label =     withCBytesUnsafe (kdfTypeToCBytes algo) $ \ algoBA ->-        withPrimVectorUnsafe secret $ \ secretBA secretOff secretLen ->+        withSecret secret $ \ psecret secretLen ->             withPrimVectorUnsafe salt $ \ saltBA saltOff saltLen ->                 withPrimVectorUnsafe label $ \ labelBA labelOff labelLen ->-                    fst <$> allocPrimVectorUnsafe siz (\ buf -> do+                    newSecret siz (\ buf -> do                         -- some kdf needs xor output buffer, so we clear it first-                        clearMBA buf siz+                        clearPtr buf siz                         throwBotanIfMinus_ $                             hs_botan_kdf algoBA buf (fromIntegral siz)-                                secretBA secretOff secretLen+                                psecret secretLen                                 saltBA saltOff saltLen                                 labelBA labelOff labelLen) @@ -119,8 +122,8 @@ kdf' :: HasCallStack      => KDFType    -- ^ the name of the given PBKDF algorithm      -> Int        -- ^ length of output key-     -> V.Bytes    -- ^ secret-     -> IO V.Bytes+     -> Secret     -- ^ secret+     -> IO Secret {-# INLINABLE kdf' #-} kdf' algo siz secret = kdf algo siz secret mempty mempty @@ -160,21 +163,21 @@ pbkdf :: HasCallStack       => PBKDFType  -- ^ PBKDF algorithm type       -> Int        -- ^ length of output key-      -> CBytes     -- ^ passphrase+      -> Password   -- ^ passphrase       -> V.Bytes    -- ^ salt-      -> IO V.Bytes+      -> IO Secret {-# INLINABLE pbkdf #-} pbkdf typ siz pwd salt = do     withCBytesUnsafe algo $ \ algoBA ->-        withCBytesUnsafe pwd $ \ pwdBA ->+        withPasswordUnsafe pwd $ \ pwdBA ->             withPrimVectorUnsafe salt $ \ saltBA saltOff saltLen -> do-                fst <$> allocPrimVectorUnsafe siz (\ buf -> do-                    clearMBA buf siz+                newSecret siz (\ buf -> do+                    clearPtr buf siz                     throwBotanIfMinus_ $                         hs_botan_pwdhash algoBA                             i1 i2 i3                             buf (fromIntegral siz)-                            pwdBA (CB.length pwd)+                            pwdBA (passwordSize pwd)                             saltBA saltOff saltLen)   where     (algo, i1, i2, i3) = pbkdfTypeToParam typ@@ -187,7 +190,7 @@            -> Int        -- ^ length of output key            -> CBytes     -- ^ passphrase            -> V.Bytes    -- ^ salt-           -> IO V.Bytes+           -> IO Secret {-# INLINABLE pbkdfTimed #-} pbkdfTimed typ msec siz pwd s = do     -- we want run it in new OS thread without stop GC from running@@ -196,7 +199,7 @@     then withCBytes algo $ \algo' ->         withCBytes pwd $ \ pwd' ->             withPrimVectorSafe s $ \s' sLen ->-                fst <$> allocPrimVectorSafe siz (\ buf -> do+                newSecret siz (\ buf -> do                     clearPtr buf siz                     throwBotanIfMinus_ $                         hs_botan_pwdhash_timed_safe@@ -205,8 +208,8 @@     else withCBytesUnsafe algo $ \algo' ->         withCBytesUnsafe pwd $ \ pwd' ->             withPrimVectorUnsafe s $ \s' sOff sLen ->-                fst <$> allocPrimVectorUnsafe siz (\ buf -> do-                    clearMBA buf siz+                newSecret siz (\ buf -> do+                    clearPtr buf siz                     throwBotanIfMinus_ $                         hs_botan_pwdhash_timed                             algo' msec buf (fromIntegral siz)
Z/Crypto/KeyWrap.hs view
@@ -10,33 +10,40 @@ This module provides RFC3394 key Wrapping. It uses a 128-bit, 192-bit, or 256-bit key to encrypt an input key. AES is always used. The input must be a multiple of 8 bytes; if not an exception is thrown.  -}-module Z.Crypto.KeyWrap where+module Z.Crypto.KeyWrap (+    -- * key wrap & unwrap+    keyWrap, keyUnwrap+    -- * re-export+  , module Z.Crypto.SafeMem+  ) where  import           Z.Botan.Exception import           Z.Botan.FFI+import           Z.Crypto.SafeMem import qualified Z.Data.Vector as V import           Z.Foreign  -- | Wrap the input key using kek (the key encryption key), and return the result. It will be 8 bytes longer than the input key. keyWrap :: HasCallStack-        => V.Bytes -- ^ key-        -> V.Bytes -- ^ kek+        => Secret   -- ^ key+        -> Secret   -- ^ kek         -> IO V.Bytes {-# INLINABLE keyWrap #-} keyWrap key kek =-    withPrimVectorUnsafe key $ \ key' keyOff keyLen ->-    withPrimVectorUnsafe kek $ \ kek' kekOff kekLen ->-    allocBotanBufferUnsafe (V.length key + 8) $-        hs_botan_key_wrap3394 key' keyOff keyLen kek' kekOff kekLen+    withSecret key $ \ key' keyLen ->+    withSecret kek $ \ kek' kekLen ->+    allocBotanBufferUnsafe (secretSize key + 8) $+        botan_key_wrap3394 key' keyLen kek' kekLen  -- | Unwrap a key wrapped with rfc3394_keywrap. keyUnwrap :: HasCallStack           => V.Bytes -- ^ wrapped key-          -> V.Bytes -- ^ kek-          -> IO V.Bytes+          -> Secret -- ^ kek+          -> IO Secret {-# INLINABLE keyUnwrap #-} keyUnwrap key kek =     withPrimVectorUnsafe key $ \ key' keyOff keyLen ->-    withPrimVectorUnsafe kek $ \ kek' kekOff kekLen ->-    allocBotanBufferUnsafe (V.length key - 8) $-        hs_botan_key_unwrap3394 key' keyOff keyLen kek' kekOff kekLen+    withSecret kek $ \ kek' kekLen ->+    let out_len = V.length key - 8+    in newSecret out_len $ \ out ->+        hs_botan_key_unwrap3394 key' keyOff keyLen kek' kekLen out (fromIntegral out_len)
Z/Crypto/MAC.hs view
@@ -28,14 +28,18 @@   -- * Internal helper   , macTypeToCBytes   , withMAC+    -- * re-export+  , HashType(..), BlockCipherType(..)+  , module Z.Crypto.SafeMem   ) where  import           GHC.Generics import           System.IO.Unsafe  (unsafePerformIO) import           Z.Botan.Exception import           Z.Botan.FFI-import           Z.Crypto.Cipher   (BlockCipherType, blockCipherTypeToCBytes)-import           Z.Crypto.Hash     (HashType, hashTypeToCBytes)+import           Z.Crypto.SafeMem+import           Z.Crypto.Cipher   (BlockCipherType(..), blockCipherTypeToCBytes)+import           Z.Crypto.Hash     (HashType(..), hashTypeToCBytes) import           Z.Data.CBytes     as CB import           Z.Data.JSON       (JSON) import qualified Z.Data.Text       as T@@ -112,12 +116,12 @@     return (MAC bs name (fromIntegral osiz))  -- | Set the random key.-setKeyMAC :: HasCallStack => MAC -> V.Bytes -> IO ()+setKeyMAC :: HasCallStack => MAC -> Secret -> IO () {-# INLINABLE setKeyMAC #-}-setKeyMAC (MAC bts _ _) bs =+setKeyMAC (MAC bts _ _) key =     withBotanStruct bts $ \pbts->-        withPrimVectorUnsafe bs $ \pbs off len ->-            throwBotanIfMinus_ (hs_botan_mac_set_key pbts pbs off len)+        withSecret key $ \ pk klen ->+            throwBotanIfMinus_ (botan_mac_set_key pbts pk klen)  -- | Feed a chunk of input into a 'MAC' object. updateMAC :: HasCallStack => MAC -> V.Bytes -> IO ()@@ -127,11 +131,11 @@         withPrimVectorUnsafe bs $ \ pbs off len ->             throwBotanIfMinus_ (hs_botan_mac_update pbts pbs off len) -finalMAC :: HasCallStack => MAC -> IO V.Bytes+finalMAC :: HasCallStack => MAC -> IO CEBytes {-# INLINABLE finalMAC #-} finalMAC (MAC bts _ siz) =     withBotanStruct bts $ \ pbts -> do-        fst <$> allocPrimVectorUnsafe siz (\ pout ->+        newCEBytesUnsafe siz (\ pout ->             throwBotanIfMinus_ (botan_mac_final pbts pout))  -- | Reset the state of MAC object back to clean, as if no input has been supplied.@@ -150,9 +154,9 @@  -- | Directly compute a message's mac mac :: HasCallStack => MACType-                    -> V.Bytes  -- ^ key+                    -> Secret   -- ^ key                     -> V.Bytes  -- ^ input-                    -> V.Bytes+                    -> CEBytes {-# INLINABLE mac #-} mac mt key inp = unsafePerformIO $ do     m <- newMAC mt@@ -161,7 +165,7 @@     finalMAC m  -- | Directly compute a chunked message's mac.-macChunks :: HasCallStack => MACType -> V.Bytes -> [V.Bytes] -> V.Bytes+macChunks :: HasCallStack => MACType -> Secret -> [V.Bytes] -> CEBytes {-# INLINABLE macChunks #-} macChunks mt key inps = unsafePerformIO $ do     m <- newMAC mt
Z/Crypto/PubKey.hs view
@@ -146,10 +146,11 @@ import           Z.Crypto.KDF        (KDFType(..), kdfTypeToCBytes) import           Z.Crypto.MPI import           Z.Crypto.RNG        (RNG, getRNG, withRNG)+import           Z.Crypto.SafeMem import qualified Z.Data.Builder      as B import           Z.Data.CBytes       (CBytes) import qualified Z.Data.CBytes       as CB-import           Z.Data.JSON       (JSON)+import           Z.Data.JSON         (JSON) import qualified Z.Data.Text         as T import qualified Z.Data.Vector       as V import           Z.Foreign@@ -1123,6 +1124,8 @@                 throwBotanIfMinus_ $ botan_pk_op_key_agreement_size op' siz')         return (KeyAgreement op (fromIntegral siz)) +-- | Produce the public value to send to other party.+-- exportKeyAgreementPublic :: HasCallStack => PrivKey -> IO V.Bytes {-# INLINABLE exportKeyAgreementPublic  #-} exportKeyAgreementPublic key =@@ -1133,16 +1136,16 @@ keyAgree ::     HasCallStack =>     KeyAgreement ->-    -- | other key+    -- | other key's public     V.Bytes ->     -- | salt     V.Bytes ->-    IO V.Bytes+    IO Secret {-# INLINABLE keyAgree  #-} keyAgree (KeyAgreement op siz) others salt =     withBotanStruct op $ \ op' ->     withPrimVectorUnsafe others $ \ others' others_off others_len ->     withPrimVectorUnsafe salt $ \ salt' salt_off salt_len ->-    allocBotanBufferUnsafe siz $ \ ret len ->-        hs_botan_pk_op_key_agreement op' ret len others'+    newSecret siz $ \ ret ->+        hs_botan_pk_op_key_agreement op' ret (fromIntegral siz) others'             others_off others_len salt' salt_off salt_len
Z/Crypto/PwdHash.hs view
@@ -20,12 +20,18 @@ Memory usage while checking a password is also a consideration; if the computation requires using a certain minimum amount of memory, then an attacker can become memory-bound, which may in particular make customized cracking hardware more expensive. Some password hashing designs, such as scrypt, explicitly attempt to provide this. The bcrypt approach requires over 4 KiB of RAM (for the Blowfish key schedule) and may also make some hardware attacks more expensive. -} -module Z.Crypto.PwdHash where+module Z.Crypto.PwdHash (+    -- * bcrypt password hash+    genBcrypt, validBcrypt+    -- * re-export+  , module Z.Crypto.SafeMem+  ) where  import           Z.Botan.Exception import           Z.Botan.FFI import           Z.Crypto.RNG       (RNG, withRNG)-import qualified Z.Data.Vector.Base as V+import           Z.Crypto.SafeMem+import qualified Z.Data.Vector      as V import           Z.Foreign  -- | Create a password hash using Bcrypt.@@ -43,33 +49,28 @@ -- The bcrypt work factor must be at least 4 (though at this work factor bcrypt is not very secure). The bcrypt format allows up to 31, but Botan currently rejects all work factors greater than 18 since even that work factor requires roughly 15 seconds of computation on a fast machine. -- genBcrypt :: HasCallStack-          => V.Bytes    -- ^ password.+          => Password   -- ^ password.           -> RNG           -> Int        -- ^ work factors (4 <= n <= 18).           -> IO V.Bytes {-# INLINABLE genBcrypt #-} genBcrypt pwd rng n = do-    withPrimVectorUnsafe pwd $ \ pwd_p pwd_off pwd_len ->+    withPasswordUnsafe pwd $ \ pwd_p ->         withRNG rng $ \ rng_p -> do-            (pa, r) <- allocPrimArrayUnsafe 64 $ \ out -> do-                throwBotanIfMinus $-                    hs_botan_bcrypt_generate out-                        pwd_p pwd_off pwd_len rng_p n 0-            let !r' = r - 1-            mpa <- unsafeThawPrimArray pa-            shrinkMutablePrimArray mpa r'-            pa' <- unsafeFreezePrimArray mpa-            return (V.PrimVector pa' 0 r')+            r <- allocBotanBufferUnsafe 64 $ \ out out_len ->+                botan_bcrypt_generate out out_len pwd_p rng_p n 0+            -- drop the NULL terminator+            return $! V.init r  -- | Takes a password and a bcrypt output and returns true if the password is the same as the one that was used to generate the bcrypt hash. -- validBcrypt :: HasCallStack-            => V.Bytes -- ^ password.-            -> V.Bytes -- ^ hash generated by 'genBcrypt'.+            => Password -- ^ password.+            -> V.Bytes  -- ^ hash generated by 'genBcrypt'.             -> IO Bool {-# INLINABLE validBcrypt #-} validBcrypt pwd hash = do-    withPrimVectorUnsafe pwd $ \ pwd_p pwd_off pwd_l ->+    withPasswordUnsafe pwd $ \ pwd_p ->         withPrimVectorUnsafe hash $ \ hash_p hash_off hash_l -> do-            ret <- hs_botan_bcrypt_is_valid  pwd_p pwd_off pwd_l hash_p hash_off hash_l+            ret <- hs_botan_bcrypt_is_valid  pwd_p hash_p hash_off hash_l             return $! ret == BOTAN_FFI_SUCCESS
+ Z/Crypto/SafeMem.hs view
@@ -0,0 +1,293 @@+module Z.Crypto.SafeMem (+  -- * Password+    Password, mkPassword, mkPasswordMaybe, passwordSize, passwordToText+  , withPasswordUnsafe, withPasswordSafe+  , InvalidPasswordException(..)+  -- * Nonce+  , Nonce, rand96bitNonce, rand128bitNonce, rand192bitNonce+  , cnt32bitNonce, cnt64bitNonce+  -- * CEBytes+  , CEBytes(..), ceBytesSize, ceBytesBitSize, newCEBytesUnsafe, newCEBytesSafe, ceBytes, unCEBytes+  -- * Secret+  , Secret, secretSize, secretBitSize, unsafeSecretFromBytes, unsafeSecretToBytes+  , newSecret, withSecret+  ) where++import           Control.Monad.Primitive+import           Data.Bits+import           Data.Char+import           Data.Int+import           Data.String+import           Data.Word+import           GHC.Prim+import           GHC.Ptr+import           Z.Botan.FFI+import           Z.Crypto.RNG+import qualified Z.Data.Builder          as B+import qualified Z.Data.CBytes           as CB+import qualified Z.Data.Text             as T+import qualified Z.Data.Text.Base        as T+import qualified Z.Data.Vector.Base      as V+import qualified Z.Data.Vector.Hex       as V+import           Z.Foreign+import           Z.IO.Exception+import           System.IO.Unsafe++-- | A type for human readable, it have+--+-- The 'Key' have the properties that:+--+-- * It's assumed to be UTF8 encoded and normalized, and does not have <https://en.wikipedia.org/wiki/Control_character control-characters>.+-- * There's no 'Eq' instance, you should always compare 'Password' via password hash.+-- * The 'Show' or 'Print' instance always print @"**PASSWORD**"@.+--+--  'Password' is not intented to be saved or transmitted, it's only useful when you want to validate a user's input against password hash.+--  See "Z.Crypto.PwdHash".+--+newtype Password = Password CB.CBytes++instance Show Password where+    show _ = "**PASSWORD**"++instance T.Print Password where+    {-# INLINABLE toUTF8BuilderP #-}+    toUTF8BuilderP _ _ = "**PASSWORD**"++instance IsString Password where+    {-# INLINABLE fromString #-}+    fromString = mkPassword . fromString++-- | Construct a password value from 'T.Text', if there're control-characters error will be thrown.+mkPassword :: HasCallStack => T.Text -> Password+{-# INLINABLE mkPassword #-}+mkPassword pwd = case mkPasswordMaybe pwd of+    Just r -> r+    _ -> throw (PasswordContainsControlCharacter callStack)++data InvalidPasswordException = PasswordContainsControlCharacter CallStack deriving Show+instance Exception InvalidPasswordException++-- | Construct a password value from 'Text', return 'Nothing' if contain control-characters.+mkPasswordMaybe :: T.Text -> Maybe Password+{-# INLINABLE mkPasswordMaybe #-}+mkPasswordMaybe pwd =+    case T.find isControl pwd of+        (_, Nothing) ->+            let pwd' = case T.isNormalized pwd of+                    T.NormalizedYes -> pwd+                    _ -> T.normalize pwd+            in Just $! Password (CB.fromText pwd')+        _ -> Nothing++-- | Byte size of a password.+passwordSize :: Password -> Int+{-# INLINABLE passwordSize #-}+passwordSize (Password pwd) = CB.length pwd++-- | Get plaintext of a password.+passwordToText :: Password -> T.Text+{-# INLINABLE passwordToText #-}+passwordToText (Password pwd) = T.Text (CB.toBytes pwd)++-- | Use password as null-terminated @const char*@, USE WITH UNSAFE FFI ONLY, PLEASE DO NOT MODIFY THE CONTENT.+withPasswordUnsafe :: Password -> (BA# Word8 -> IO r) -> IO r+{-# INLINABLE withPasswordUnsafe #-}+withPasswordUnsafe (Password pwd) = CB.withCBytesUnsafe pwd++-- | Use password as null-terminated @const char*@, PLEASE DO NOT MODIFY THE CONTENT.+withPasswordSafe :: Password -> (Ptr Word8 -> IO r) -> IO r+{-# INLINABLE withPasswordSafe #-}+withPasswordSafe (Password pwd) = CB.withCBytes pwd++--------------------------------------------------------------------------------++-- | A value used only once in AEAD modes.+--+-- We use also this type to represent IV(initialization vector) for stream ciphers, but the way a nonce is generated is different:+-- random IV is one generation choice which is usually fine, while Nonce can also be a counter, which is not ok for CBC mode.+--+-- Some common nonce size:+--+-- * 96bit for GCM AEAD, ChaCha20Poly1305.+-- * 128bit for XChaCha20Poly1305.+-- * Block size for CBC IV(e.g. 128 bits for AES).+--+type Nonce = V.Bytes++-- | Get 64-bit random nonce.+rand96bitNonce :: RNG -> IO Nonce+{-# INLINABLE rand96bitNonce #-}+rand96bitNonce rng = getRandom rng 12++-- | Get 128-bit random nonce.+rand128bitNonce :: RNG -> IO Nonce+{-# INLINABLE rand128bitNonce #-}+rand128bitNonce rng = getRandom rng 16++-- | Get 192-bit random nonce.+rand192bitNonce :: RNG -> IO Nonce+{-# INLINABLE rand192bitNonce #-}+rand192bitNonce rng = getRandom rng 24++-- | Get 32bit nonce from counter.+cnt32bitNonce :: Int32 -> Nonce+{-# INLINABLE cnt32bitNonce #-}+cnt32bitNonce c = B.build $ B.encodePrimBE c++-- | Get 64bit nonce from counter.+cnt64bitNonce :: Int64 -> Nonce+{-# INLINABLE cnt64bitNonce #-}+cnt64bitNonce c = B.build $ B.encodePrimBE c++--------------------------------------------------------------------------------++-- | Constant-time equal comparing bytes.+--+-- It comes with following property:+--+-- * The 'Eq' instance gives you constant-time compare.+-- * The 'Show' and 'T.Print' instances give you hex encoding.+--+newtype CEBytes = CEBytes (PrimArray Word8)++ceBytesSize :: CEBytes -> Int+{-# INLINABLE ceBytesSize #-}+ceBytesSize (CEBytes d) = sizeofPrimArray d++ceBytesBitSize :: CEBytes -> Int+{-# INLINABLE ceBytesBitSize #-}+ceBytesBitSize (CEBytes d) = 8 * (V.length d)++instance Eq CEBytes where+    {-# INLINABLE (==) #-}+    (CEBytes pa@(PrimArray ba#)) == (CEBytes pb@(PrimArray bb#)) =+        la == lb && botan_constant_time_compare_ba ba# bb# (fromIntegral la) == 0+      where+        la = sizeofPrimArray pa+        lb = sizeofPrimArray pb++instance Show CEBytes where+    show = T.toString++instance T.Print CEBytes where+    toUTF8BuilderP _ = V.hexEncodeBuilder True . unCEBytes++-- | Create a ceBytes from unsafe FFI.+newCEBytesUnsafe :: Int -> (MBA# Word8 -> IO r) -> IO CEBytes+{-# INLINABLE newCEBytesUnsafe #-}+newCEBytesUnsafe len f = do+    (d, _) <- allocPrimArrayUnsafe len f+    pure (CEBytes d)++-- | Create a ceBytes from safe FFI.+newCEBytesSafe :: Int -> (Ptr Word8 -> IO r) -> IO CEBytes+{-# INLINABLE newCEBytesSafe #-}+newCEBytesSafe len f = do+    (d, _) <- allocPrimArraySafe len f+    pure (CEBytes d)++-- | Create a 'CEBytes' from 'V.Bytes'.+ceBytes :: V.Bytes -> CEBytes+{-# INLINABLE ceBytes #-}+ceBytes = CEBytes . V.arrVec++-- | Get 'CEBytes' 's content as 'V.Bytes', by doing this you lose the constant-time comparing.+unCEBytes :: CEBytes -> V.Bytes+{-# INLINABLE unCEBytes #-}+unCEBytes (CEBytes d) = V.arrVec d++--------------------------------------------------------------------------------++-- | Memory allocated by locked allocator and will be zeroed after used.+--+-- * It's allocated by botan's locking allocator(which means it will not get swapped to disk) if possible.+-- * It will zero the memory it used once get GCed.+-- * The 'Eq' instance gives you constant-time compare.+-- * The 'Show' or 'Print' instance always print @"**SECRET**"@.+--+--  'Secret' is not intented to be saved or transmitted, there're several way to obtain a 'Secret':+--+--  + Use 'unsafeSecretFromBytes' to convert a piece of 'Bytes' to 'Secret'.+--  + Use key-exchanges from 'Z.Crypto.PubKey'.+--  + Unwrap a key, see 'Z.Crypto.KeyWrap'.+--+newtype Secret = Secret (PrimArray (Ptr Word8))++instance Show Secret where+    show _ = "**SECRET**"++instance T.Print Secret where+    {-# INLINABLE toUTF8BuilderP #-}+    toUTF8BuilderP _ _ = "**SECRET**"++-- | This instance will break the no-tracing property by saving secret in compiled and loaded binary.+instance IsString Secret where+    {-# INLINABLE fromString #-}+    fromString = unsafePerformIO . unsafeSecretFromBytes . fromString++-- | Constant-time compare+instance Eq Secret where+    {-# INLINABLE (==) #-}+    a@(Secret pa) == b@(Secret pb) =+        la == lb && botan_constant_time_compare (indexPrimArray pa 0) (indexPrimArray pb 0) (fromIntegral la) == 0+      where+        la = secretSize a+        lb = secretSize b++-- | Get secret key's byte length.+secretSize :: Secret -> Int+{-# INLINABLE secretSize #-}+secretSize (Secret pa) = (indexPrimArray pa 1) `minusPtr` (indexPrimArray pa 0)++-- | Get secret key's bit size.+secretBitSize :: Secret -> Int+{-# INLINABLE secretBitSize #-}+secretBitSize k = secretSize k `unsafeShiftL` 3++-- | Unsafe convert a 'V.Bytes' to a 'Secret'.+--+-- Note the original 'V.Bytes' may get moved by GC or swapped to disk, which may defeat the purpose of using a 'Secret'.+unsafeSecretFromBytes :: V.Bytes -> IO Secret+{-# INLINABLE unsafeSecretFromBytes #-}+unsafeSecretFromBytes (V.PrimVector pa poff plen) = newSecret plen $ \ p ->+    copyPrimArrayToPtr p pa poff plen++-- | Unsafe convert a 'V.Bytes' from a 'Secret'.+--+-- Note the result 'V.Bytes' may get moved by GC or swapped to disk, which may defeat the purpose of using a 'Secret'.+unsafeSecretToBytes :: Secret -> IO V.Bytes+{-# INLINABLE unsafeSecretToBytes #-}+unsafeSecretToBytes key = withSecret key $ \ p len ->+    let len' = fromIntegral len+    in fst <$> allocPrimVectorUnsafe len' (\ p' ->+        copyPtrToMutablePrimArray (MutablePrimArray p') 0 p len')++-- | Initialize a 'Secret' which pass an allocated pointer pointing to zeros to a init function.+newSecret :: Int -> (Ptr Word8 -> IO r) -> IO Secret+{-# INLINABLE newSecret #-}+newSecret len f = mask_ $ do+    mpa <- newPrimArray 2+    p@(Ptr addr#) <- hs_botan_allocate_memory len+    _ <- f p `onException` hs_botan_deallocate_memory (p `plusPtr` len) p+    let !p'@(Ptr addr'#) = p `plusPtr` len+    writePrimArray mpa 0 p+    writePrimArray mpa 1 p'+    pa@(PrimArray ba#) <- unsafeFreezePrimArray mpa+    primitive_ $ \ s0# ->+        let !(# s1#, w# #) = mkWeakNoFinalizer# ba# () s0#+            !(# s2#, _ #) = addCFinalizerToWeak# fin# addr# 1# addr'# w# s1#+        in s2#+    return (Secret pa)+  where+    !(FunPtr fin#) = hs_botan_deallocate_memory_p++-- | Use 'Secret' as a @const char*@, PLEASE DO NOT MODIFY THE CONTENT.+--+withSecret :: Secret -> (Ptr Word8 -> CSize -> IO r) -> IO r+{-# INLINABLE withSecret #-}+withSecret (Secret pa@(PrimArray ba#)) f = do+    let p   = indexPrimArray pa 0+        p'  = indexPrimArray pa 1+    x <- f p (fromIntegral $ p' `minusPtr` p)+    primitive_ (touch# ba#)+    return x
− cbits/hs_botan.c
@@ -1,376 +0,0 @@-#include <hs_botan.h>-#include <string.h>--////////////////////////////////////////////////////////////////////////////////-// FFI Helper-// Codec--int hs_botan_hex_encode(const uint8_t *x, HsInt x_off, HsInt x_len, char *out){-    return botan_hex_encode(x+x_off, x_len, out, 0);-}-int hs_botan_hex_encode_lower(const uint8_t *x, HsInt x_off, HsInt x_len, char *out){-    return botan_hex_encode(x+x_off, x_len, out, BOTAN_FFI_HEX_LOWER_CASE);-}-HsInt hs_botan_hex_decode(const char* hex_str, HsInt in_off, HsInt in_len, uint8_t* out){-    size_t* out_size;-    int r = botan_hex_decode(hex_str+in_off, in_len, out, out_size);-    if (r < 0) return (HsInt)r;-    return (HsInt)out_size;-}--// RNG--int hs_botan_rng_add_entropy(botan_rng_t rng, const uint8_t *seed, HsInt off, HsInt len){-    return botan_rng_add_entropy(rng, seed+off, len);-}--// Block cipher-int hs_botan_block_cipher_set_key(botan_block_cipher_t bc, const uint8_t *key, HsInt key_off, HsInt key_len){-    return botan_block_cipher_set_key(bc, key+key_off, key_len);-}-int hs_botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc-    , const uint8_t in[], HsInt off, uint8_t out[], HsInt blocks){-    return botan_block_cipher_encrypt_blocks(bc, in+off, out, blocks);-}-int hs_botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc-    , const uint8_t in[], HsInt off, uint8_t out[], HsInt blocks){-    return botan_block_cipher_decrypt_blocks(bc, in+off, out, blocks);-}--// Hash-int hs_botan_hash_update(botan_hash_t hash, const uint8_t *input, HsInt off, HsInt len){-    return botan_hash_update(hash, input+off, len);-}--// Cipher Mode-int hs_botan_cipher_set_associated_data(botan_cipher_t cipher, const uint8_t* ad, HsInt ad_off, HsInt ad_len){-    return botan_cipher_set_associated_data(cipher, ad+ad_off, ad_len);-}--int hs_botan_cipher_set_key(botan_cipher_t cipher, const uint8_t* key, HsInt key_off, HsInt key_len){-    return botan_cipher_set_key(cipher, key+key_off, key_len);-}--int hs_botan_cipher_start(botan_cipher_t cipher, const uint8_t* nonce, HsInt nonce_off, HsInt nonce_len){-    return botan_cipher_start(cipher, nonce+nonce_off, nonce_len);-}--HsInt hs_botan_cipher_update(botan_cipher_t cipher,-                           uint8_t* output,-                           const uint8_t* input,-                           HsInt input_off,-                           HsInt input_len){-    size_t input_consumed, output_written;-    int r = botan_cipher_update(cipher, 0, output, input_len-        , &output_written, input+input_off, input_len, &input_consumed);-    if (r < 0){-        return (HsInt)r;-    } else {-        return (HsInt)output_written;-    }-}--HsInt hs_botan_cipher_finish(botan_cipher_t cipher,-                           uint8_t* output,-                           HsInt output_len,-                           const uint8_t* input,-                           HsInt input_off,-                           HsInt input_len){-    size_t input_consumed, output_written;-    int r = botan_cipher_update(cipher, BOTAN_CIPHER_UPDATE_FLAG_FINAL, output, output_len-        , &output_written, input+input_off, input_len, &input_consumed);-    if (r < 0){-        return (HsInt)r;-    } else {-        return (HsInt)output_written;-    }-}--// Multiple Precision Integers-int hs_botan_mp_to_hex(botan_mp_t mp, char *out, HsInt off){-    return botan_mp_to_hex(mp, out+off);-}-HsInt hs_botan_mp_to_dec(botan_mp_t mp, char *out, HsInt off){-    size_t len;-    int r = botan_mp_to_str(mp, 10, out+off, &len);-    if (r >= 0) {-        return (HsInt)len+off-1;-    } else {-        return (HsInt)r;-    }-}-int hs_botan_mp_set_from_hex(botan_mp_t dest, const char *str, HsInt off, HsInt len){-    char temp[len+3];-    temp[0] = '0';-    temp[1] = 'x';-    memcpy(temp+2, str+off, len);-    temp[len+2] = 0;-    return botan_mp_set_from_str(dest, temp);--}-int hs_botan_mp_set_from_dec(botan_mp_t dest, const char *str, HsInt off, HsInt len){-    char temp[len+1];-    memcpy(temp, str+off, len);-    temp[len] = 0;-    return botan_mp_set_from_str(dest, temp);-}-int hs_botan_mp_from_bin(botan_mp_t mp, const uint8_t* vec, HsInt off, HsInt len){-    return botan_mp_from_bin(mp, vec+off, len);-}-int hs_botan_mp_to_bin(botan_mp_t mp, uint8_t* vec, HsInt off){-    return botan_mp_to_bin(mp, vec+off);-}--// KDF & PBKDF--int hs_botan_kdf(const char* algo-                ,uint8_t out[], HsInt out_len-                ,const uint8_t passwd[], HsInt passwd_off, HsInt passwd_len-                ,const uint8_t salt[], HsInt salt_off, HsInt salt_len-                ,const uint8_t label[], HsInt label_off, HsInt label_len){-    return botan_kdf(algo, out, out_len, passwd+passwd_off, passwd_len, salt+salt_off, salt_len, label+label_off, label_len);-}--int hs_botan_pwdhash(const char* algo-                    ,HsInt p1, HsInt p2, HsInt p3-                    ,uint8_t out[], HsInt out_len-                    ,const char* passwd, HsInt passwd_len-                    ,const uint8_t salt[], HsInt salt_off, HsInt salt_len){-    return botan_pwdhash(algo, p1, p2, p3, out, out_len, passwd, passwd_len, salt+salt_off, salt_len);-}--int hs_botan_pwdhash_timed(const char* algo-                          ,uint32_t msec-                          ,uint8_t out[], HsInt out_len-                          ,const char* passwd, HsInt passwd_len-                          ,const uint8_t salt[], HsInt salt_off, HsInt salt_len){-    return botan_pwdhash_timed(algo, msec, NULL, NULL, NULL, out, out_len, passwd, passwd_len, salt+salt_off, salt_len);-}--HsInt hs_botan_bcrypt_generate(uint8_t *out, const char *pwd, HsInt pwd_off, HsInt pwd_len-    , botan_rng_t rng, HsInt work_factor, uint32_t flags){-    size_t out_len = 64;-    char pwd0[pwd_len+1];--    memcpy(pwd0, pwd+pwd_off, pwd_len);-    pwd0[pwd_len] = 0;--    int r = botan_bcrypt_generate(out, &out_len, pwd0, rng, work_factor, flags);-    if (r < 0) {-        return (HsInt)r;-    } else {-        return (HsInt)out_len;-    }-}--int hs_botan_bcrypt_is_valid(const char* pwd, HsInt pwd_off, HsInt pwd_len-    , const char* hash, HsInt hash_off, HsInt hash_len){-    char pwd0[pwd_len+1];-    char hash0[hash_len+1];--    memcpy(pwd0, pwd+pwd_off, pwd_len);-    pwd0[pwd_len] = 0;-    memcpy(hash0, hash+hash_off, hash_len);-    hash0[hash_len] = 0;--    return botan_bcrypt_is_valid(pwd0, hash0);-}--// MAC--int hs_botan_mac_set_key(botan_mac_t mac, const uint8_t* key, HsInt key_off, HsInt key_len){-    return botan_mac_set_key(mac, key+key_off, key_len);-}-int hs_botan_mac_update(botan_mac_t mac, const uint8_t* buf, HsInt off ,HsInt len){-    return botan_mac_update(mac, buf + off, len);-}--int hs_botan_mac_final(botan_mac_t mac, uint8_t out[]){-    return botan_mac_final(mac, out);-}-int hs_botan_mac_clear(botan_mac_t mac){-    return botan_mac_clear(mac);-}--int hs_botan_mac_name(botan_mac_t mac, char* name, size_t* name_len){-    return botan_mac_name(mac, name, name_len);-}-int hs_botan_mac_get_keyspec(botan_mac_t mac,-    size_t* out_minimum_keylength,-    size_t* out_maximum_keylength,-    size_t* out_keylength_modulo){-        return botan_mac_get_keyspec(mac, out_minimum_keylength, out_maximum_keylength, out_keylength_modulo);-}--// Public Key Creation, Import and Export--int hs_botan_privkey_load (botan_privkey_t* key, botan_rng_t rng-                          ,const uint8_t bits[], HsInt off, HsInt len-                          ,const char* passwd){-    if (*passwd == '\0') passwd = NULL;-    return botan_privkey_load(key, rng, bits+off, len, passwd);-}--int hs_botan_pubkey_load (botan_pubkey_t* key-                         ,const uint8_t bits[], HsInt off, HsInt len){-    return botan_pubkey_load(key, bits+off, len);-}--// Public Key Encryption / Decryption--int hs_botan_pk_op_encrypt(botan_pk_op_encrypt_t op, botan_rng_t rng, uint8_t out[], HsInt *out_len, const uint8_t plaintext[], HsInt plaintext_off, HsInt plaintext_len){-    return botan_pk_op_encrypt(op, rng, out, out_len, plaintext+plaintext_off, plaintext_len);-}--int hs_botan_pk_op_decrypt(botan_pk_op_decrypt_t op, uint8_t out[], HsInt *out_len, uint8_t ciphertext[], HsInt ciphertext_off, HsInt ciphertext_len){-    return botan_pk_op_decrypt(op, out, out_len, ciphertext+ciphertext_off, ciphertext_len);-}--// Signature Generation & Signature Verification--int hs_botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], HsInt off, HsInt len){-    return botan_pk_op_sign_update(op, in+off, len);-}--int hs_botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], HsInt off, HsInt len){-    return botan_pk_op_verify_update(op, in+off, len);-}--int hs_botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], HsInt off, HsInt len){-    return botan_pk_op_verify_finish(op, sig+off, len);-}--// Key Agreement--int hs_botan_pk_op_key_agreement(botan_pk_op_ka_t op, uint8_t out[], HsInt *out_len, const uint8_t other_key[], HsInt other_key_off, HsInt other_key_len, const uint8_t salt[], HsInt salt_off, HsInt salt_len){-    return botan_pk_op_key_agreement(op, out, out_len, other_key+other_key_off, other_key_len, salt+salt_off, salt_len);-}--/*-int hs_botan_mceies_encrypt(botan_pubkey_t mce_key, botan_rng_t rng, const char *aead, const uint8_t pt[], HsInt pt_off, HsInt pt_len, const uint8_t ad[], HsInt ad_off, HsInt ad_len, uint8_t ct[], HsInt *ct_len){-    return botan_mceies_encrypt(mce_key, rng, aead, pt+pt_off, pt_len, ad+ad_off, ad_len, ct, ct_len);-}-*/--// X.509 Certificates & Certificate Revocation Lists--int hs_botan_x509_cert_load(botan_x509_cert_t *cert_obj, const uint8_t cert[], HsInt cert_off, HsInt cert_len){-    return botan_x509_cert_load(cert_obj, cert+cert_off, cert_len);-}--int hs_botan_x509_cert_verify(botan_x509_cert_t cert-        , const botan_x509_cert_t *intermediates, HsInt intermediates_len-        , const botan_x509_cert_t *trusted, HsInt trusted_len-        , HsInt required_strength, const char *hostname, uint64_t reference_time){-    int r1;-    int r2 = botan_x509_cert_verify(&r1, cert-            , intermediates, intermediates_len-            , trusted, trusted_len-            , NULL, required_strength, hostname, reference_time);-    if (r2 < 0){-        return r2;-    } else { -        return r1; -    }-}--int hs_botan_x509_cert_verify_with_crl(botan_x509_cert_t cert-        , const botan_x509_cert_t *intermediates, HsInt intermediates_len-        , const botan_x509_cert_t *trusted, HsInt trusted_len-        , const botan_x509_crl_t *crls, HsInt crls_len-        , HsInt required_strength, const char *hostname, uint64_t reference_time){-    int r1;-    int r2 = botan_x509_cert_verify_with_crl(&r1, cert-            , intermediates, intermediates_len-            , trusted, trusted_len-            , crls, crls_len-            , NULL, required_strength, hostname, reference_time);-    if (r2 < 0){-        return r2;-    } else { -        return r1; -    }-}---int hs_botan_x509_cert_verify_with_certstore_crl(-   botan_x509_cert_t cert,-   const botan_x509_cert_t* intermediates, HsInt intermediates_len,-   const botan_x509_certstore_t store,-   const botan_x509_crl_t* crls, HsInt crls_len,-   size_t required_strength,-   const char* hostname,-   uint64_t reference_time) {-    int r1;-    int r2 = botan_x509_cert_verify_with_certstore_crl(&r1, cert-            , intermediates, intermediates_len-            , store-            , crls, crls_len-            , required_strength, hostname, reference_time);-    if (r2 < 0){-        return r2;-    } else { -        return r1; -    }--}--int hs_botan_x509_crl_load(botan_x509_crl_t *crl_obj, const uint8_t crl[], HsInt crl_off, HsInt crl_len){-    return botan_x509_crl_load(crl_obj, crl+crl_off, crl_len);-}--// Key wrap--/**-  * Advanced Encryption Standard (AES) Key Wrap Algorithm-  * See `https://tools.ietf.org/html/rfc3394`.-  * Key wrapping as per RFC 3394-*/--int hs_botan_key_wrap3394(const uint8_t key[], HsInt key_off, HsInt key_len-                         ,const uint8_t kek[], HsInt kek_off, HsInt kek_len-                         ,uint8_t wrapped_key[], size_t *wrapped_key_len)-{-    return botan_key_wrap3394(key+key_off, key_len-                             ,kek+kek_off, kek_len-                             ,wrapped_key, wrapped_key_len);-}--int hs_botan_key_unwrap3394(const uint8_t wrapped_key[], HsInt wrapped_key_off, HsInt wrapped_key_len-                           ,const uint8_t kek[], HsInt kek_off, HsInt kek_len-                           ,uint8_t key[], size_t *key_len){-    return botan_key_unwrap3394(wrapped_key+wrapped_key_off, wrapped_key_len-                               ,kek+kek_off, kek_len-                               ,key, key_len);}--// OTP--int hs_botan_hotp_init(botan_hotp_t* hotp-                      ,const uint8_t key[], HsInt key_off, HsInt key_len-                      ,const char* hash_algo-                      ,HsInt digits){-    return botan_hotp_init(hotp-                          ,key+key_off, key_len-                          ,hash_algo, digits);}--int hs_botan_totp_init(botan_totp_t* totp-                      ,const uint8_t key[], HsInt key_off, HsInt key_len-                      ,const char* hash_algo-                      ,HsInt digits-                      ,HsInt time_step){-    return botan_totp_init(totp, key+key_off, key_len, hash_algo, digits, time_step);}--// FPE--int hs_botan_fpe_fe1_init(botan_fpe_t* fpe, botan_mp_t n,-                       const uint8_t key[], HsInt key_off, HsInt key_len,-                       size_t rounds, uint32_t flags){-return botan_fpe_fe1_init(fpe, n,-                       key+key_off, key_len,-                       rounds, flags);}--int hs_botan_fpe_encrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], HsInt tweak_off, HsInt tweak_len)-{return botan_fpe_encrypt(fpe, x, tweak+tweak_off, tweak_len);}--int hs_botan_fpe_decrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], HsInt tweak_off, HsInt tweak_len)-{return botan_fpe_decrypt(fpe, x, tweak+tweak_off, tweak_len);}
+ cbits/hs_botan_certstore.cpp view
@@ -0,0 +1,161 @@+#include <botan/ffi.h>+#include <botan/internal/ffi_util.h>+#include <botan/internal/ffi_pkey.h>++#include <botan/x509cert.h>+#include <botan/x509path.h>+#include <botan/x509_crl.h>+#include <botan/certstor.h>+#include <botan/data_src.h>++#if defined(BOTAN_HAS_CERTSTOR_FLATFILE)+    #include <botan/certstor_flatfile.h>+#endif++#if defined(BOTAN_HAS_CERTSTOR_MACOS)+    #include <botan/certstor_macos.h>+#elif defined(BOTAN_HAS_CERTSTOR_WINDOWS)+    #include <botan/certstor_windows.h>+#endif+#include <HsFFI.h>+#include <string.h>++extern "C" {++using namespace Botan_FFI;++// Cert Store++BOTAN_FFI_DECLARE_STRUCT(botan_x509_certstore_struct, Botan::Certificate_Store, 0x8BD3442A);++typedef struct botan_x509_certstore_struct* botan_x509_certstore_t;++int botan_x509_certstore_load_file(botan_x509_certstore_t* certstore_obj, const char* certstore_path)+    {+    if(!certstore_obj || !certstore_path)+        return BOTAN_FFI_ERROR_NULL_POINTER;++#if defined(BOTAN_HAS_CERTSTOR_FLATFILE)++    return ffi_guard_thunk(__func__, [=]() -> int {+        std::unique_ptr<Botan::Certificate_Store> c(new Botan::Flatfile_Certificate_Store(certstore_path));+        *certstore_obj = new botan_x509_certstore_struct(c.release());+        return BOTAN_FFI_SUCCESS;+        });++#else+    return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;+#endif+    }++int botan_x509_certstore_load_system(botan_x509_certstore_t* certstore_obj)+    {+    if(!certstore_obj)+        return BOTAN_FFI_ERROR_NULL_POINTER;+++    return ffi_guard_thunk(__func__, [=]() -> int {+#if defined(BOTAN_HAS_CERTSTOR_MACOS)+        std::unique_ptr<Botan::Certificate_Store> c(new Botan::Certificate_Store_MacOS);+#elif defined(BOTAN_HAS_CERTSTOR_WINDOWS)+        std::unique_ptr<Botan::Certificate_Store> c(new Botan::Certificate_Store_Windows);+#elif defined(BOTAN_HAS_CERTSTOR_FLATFILE) && defined(BOTAN_SYSTEM_CERT_BUNDLE)+        std::unique_ptr<Botan::Certificate_Store> c(+             new Botan::Flatfile_Certificate_Store(BOTAN_SYSTEM_CERT_BUNDLE, true));+#else+        return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;+#endif+        *certstore_obj = new botan_x509_certstore_struct(c.release());+        return BOTAN_FFI_SUCCESS;+        });++    }++int botan_x509_certstore_destroy(botan_x509_certstore_t certstore)+    {+    return BOTAN_FFI_CHECKED_DELETE(certstore);+    }++int botan_x509_cert_verify_with_certstore_crl(+    int* result_code,+    botan_x509_cert_t cert,+    const botan_x509_cert_t* intermediates,+    size_t intermediates_len,+    const botan_x509_certstore_t store,+    const botan_x509_crl_t* crls,+    size_t crls_len,+    size_t required_strength,+    const char* hostname_cstr,+    uint64_t reference_time)+    {+    if(required_strength == 0)+        required_strength = 110;++    return ffi_guard_thunk(__func__, [=]() -> int {+        const std::string hostname((hostname_cstr == nullptr) ? "" : hostname_cstr);+        const Botan::Usage_Type usage = Botan::Usage_Type::UNSPECIFIED;+        const auto validation_time = reference_time == 0 ?+            std::chrono::system_clock::now() :+            std::chrono::system_clock::from_time_t(static_cast<time_t>(reference_time));++        std::vector<Botan::X509_Certificate> end_certs;+        end_certs.push_back(safe_get((Botan_FFI::botan_struct<Botan::X509_Certificate, 0x8F628937>*)cert));+        for(size_t i = 0; i != intermediates_len; ++i)+            end_certs.push_back(safe_get((Botan_FFI::botan_struct<Botan::X509_Certificate, 0x8F628937>*)intermediates[i]));++        std::vector<Botan::Certificate_Store*> trusted_roots;+        std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_crls;+        trusted_roots.push_back(&safe_get(store));++        if(crls_len > 0)+            {+            trusted_crls.reset(new Botan::Certificate_Store_In_Memory);+            for(size_t i = 0; i != crls_len; ++i)+                {+                trusted_crls->add_crl(safe_get((Botan_FFI::botan_struct<Botan::X509_CRL, 0x2C628910>*)crls[i]));+                }+            trusted_roots.push_back(trusted_crls.get());+            }++        Botan::Path_Validation_Restrictions restrictions(false, required_strength);++        auto validation_result = Botan::x509_path_validate(end_certs,+                                                                            restrictions,+                                                                            trusted_roots,+                                                                            hostname,+                                                                            usage,+                                                                            validation_time);++        if(result_code)+            *result_code = static_cast<int>(validation_result.result());++        if(validation_result.successful_validation())+            return 0;+        else+            return 1;+        });+    }++int hs_botan_x509_cert_verify_with_certstore_crl(+    botan_x509_cert_t cert,+    const botan_x509_cert_t* intermediates, HsInt intermediates_len,+    const botan_x509_certstore_t store,+    const botan_x509_crl_t* crls, HsInt crls_len,+    size_t required_strength,+    const char* hostname,+    uint64_t reference_time) {+     int r1;+     int r2 = botan_x509_cert_verify_with_certstore_crl(&r1, cert+                , intermediates, intermediates_len+                , store+                , crls, crls_len+                , required_strength, hostname, reference_time);+     if (r2 < 0){+          return r2;+     } else { +          return r1; +     }++    }++}
+ cbits/hs_botan_extra.cpp view
@@ -0,0 +1,311 @@+#include <botan/ffi.h>+#include <botan/internal/ffi_util.h>+#include <botan/aead.h>+#include <HsFFI.h>+#include <string.h>++extern "C" {++using namespace Botan_FFI;++// Mem helper+++uint8_t* hs_botan_allocate_memory(HsInt size){+    return (uint8_t*)Botan::allocate_memory(size, 1);+}+    +void hs_botan_deallocate_memory(uint8_t* eptr, uint8_t* ptr){+     Botan::deallocate_memory(ptr, eptr-ptr, 1);+}++////////////////////////////////////////////////////////////////////////////////+// RNG++int hs_botan_rng_add_entropy(botan_rng_t rng, const uint8_t *seed, HsInt off, HsInt len){+    return botan_rng_add_entropy(rng, seed+off, len);+}++// Block cipher+int hs_botan_block_cipher_set_key(botan_block_cipher_t bc, const uint8_t *key, HsInt key_off, HsInt key_len){+    return botan_block_cipher_set_key(bc, key+key_off, key_len);+}+int hs_botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc+    , const uint8_t in[], HsInt off, uint8_t out[], HsInt blocks){+    return botan_block_cipher_encrypt_blocks(bc, in+off, out, blocks);+}+int hs_botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc+    , const uint8_t in[], HsInt off, uint8_t out[], HsInt blocks){+    return botan_block_cipher_decrypt_blocks(bc, in+off, out, blocks);+}++// Hash+int hs_botan_hash_update(botan_hash_t hash, const uint8_t *input, HsInt off, HsInt len){+    return botan_hash_update(hash, input+off, len);+}++// Cipher Mode+int hs_botan_cipher_set_associated_data(botan_cipher_t cipher, const uint8_t* ad, HsInt ad_off, HsInt ad_len){+    return botan_cipher_set_associated_data(cipher, ad+ad_off, ad_len);+}++int hs_botan_cipher_start(botan_cipher_t cipher, const uint8_t* nonce, HsInt nonce_off, HsInt nonce_len){+    return botan_cipher_start(cipher, nonce+nonce_off, nonce_len);+}++HsInt hs_botan_cipher_output_size(botan_cipher_t cipher, HsInt input_len){+    return (HsInt)BOTAN_FFI_DO(Botan::Cipher_Mode, +        (botan_struct<Botan::Cipher_Mode, 0xB4A2BF9C>*)cipher, c, +            { return c.output_length((size_t)input_len) + c.update_granularity(); });+}++HsInt hs_botan_cipher_finish(botan_cipher_t cipher,+                           uint8_t* output,+                           HsInt output_len,+                           const uint8_t* input,+                           HsInt input_off,+                           HsInt input_len){+    size_t input_consumed, output_written;+    int r = botan_cipher_update(cipher, BOTAN_CIPHER_UPDATE_FLAG_FINAL, output, output_len+        , &output_written, input+input_off, input_len, &input_consumed);+    if (r < 0){+        return (HsInt)r;+    } else {+        return (HsInt)output_written;+    }+}++// Multiple Precision Integers+int hs_botan_mp_to_hex(botan_mp_t mp, char *out, HsInt off){+    return botan_mp_to_hex(mp, out+off);+}+HsInt hs_botan_mp_to_dec(botan_mp_t mp, char *out, HsInt off){+    size_t len;+    int r = botan_mp_to_str(mp, 10, out+off, &len);+    if (r >= 0) {+        return (HsInt)len+off-1;+    } else {+        return (HsInt)r;+    }+}+int hs_botan_mp_set_from_hex(botan_mp_t dest, const char *str, HsInt off, HsInt len){+    char temp[len+3];+    temp[0] = '0';+    temp[1] = 'x';+    memcpy(temp+2, str+off, len);+    temp[len+2] = 0;+    return botan_mp_set_from_str(dest, temp);++}+int hs_botan_mp_set_from_dec(botan_mp_t dest, const char *str, HsInt off, HsInt len){+    char temp[len+1];+    memcpy(temp, str+off, len);+    temp[len] = 0;+    return botan_mp_set_from_str(dest, temp);+}+int hs_botan_mp_from_bin(botan_mp_t mp, const uint8_t* vec, HsInt off, HsInt len){+    return botan_mp_from_bin(mp, vec+off, len);+}+int hs_botan_mp_to_bin(botan_mp_t mp, uint8_t* vec, HsInt off){+    return botan_mp_to_bin(mp, vec+off);+}++// KDF & PBKDF++int hs_botan_kdf(const char* algo+                ,uint8_t out[], size_t out_len+                ,const uint8_t secret[], size_t secret_len+                ,const uint8_t salt[], HsInt salt_off, HsInt salt_len+                ,const uint8_t label[], HsInt label_off, HsInt label_len){+    return botan_kdf(algo, out, out_len, secret, secret_len, salt+salt_off, salt_len, label+label_off, label_len);+}++int hs_botan_pwdhash(const char* algo+                    ,HsInt p1, HsInt p2, HsInt p3+                    ,uint8_t out[], HsInt out_len+                    ,const char* passwd, HsInt passwd_len+                    ,const uint8_t salt[], HsInt salt_off, HsInt salt_len){+    return botan_pwdhash(algo, p1, p2, p3, out, out_len, passwd, passwd_len, salt+salt_off, salt_len);+}++int hs_botan_pwdhash_timed(const char* algo+                          ,uint32_t msec+                          ,uint8_t out[], HsInt out_len+                          ,const char* passwd, HsInt passwd_len+                          ,const uint8_t salt[], HsInt salt_off, HsInt salt_len){+    return botan_pwdhash_timed(algo, msec, NULL, NULL, NULL, out, out_len, passwd, passwd_len, salt+salt_off, salt_len);+}++int hs_botan_bcrypt_is_valid(const char* pwd, const char* hash, HsInt hash_off, HsInt hash_len){++    char hash0[hash_len+1];+    memcpy(hash0, hash+hash_off, hash_len);+    hash0[hash_len] = 0;++    return botan_bcrypt_is_valid(pwd, hash0);+}++// MAC++int hs_botan_mac_set_key(botan_mac_t mac, const uint8_t* key, HsInt key_off, HsInt key_len){+    return botan_mac_set_key(mac, key+key_off, key_len);+}+int hs_botan_mac_update(botan_mac_t mac, const uint8_t* buf, HsInt off ,HsInt len){+    return botan_mac_update(mac, buf + off, len);+}++int hs_botan_mac_final(botan_mac_t mac, uint8_t out[]){+    return botan_mac_final(mac, out);+}+int hs_botan_mac_clear(botan_mac_t mac){+    return botan_mac_clear(mac);+}++int hs_botan_mac_name(botan_mac_t mac, char* name, size_t* name_len){+    return botan_mac_name(mac, name, name_len);+}+int hs_botan_mac_get_keyspec(botan_mac_t mac,+    size_t* out_minimum_keylength,+    size_t* out_maximum_keylength,+    size_t* out_keylength_modulo){+        return botan_mac_get_keyspec(mac, out_minimum_keylength, out_maximum_keylength, out_keylength_modulo);+}++// Public Key Creation, Import and Export++int hs_botan_privkey_load (botan_privkey_t* key, botan_rng_t rng+                          ,const uint8_t bits[], HsInt off, HsInt len+                          ,const char* passwd){+    if (*passwd == '\0') passwd = NULL;+    return botan_privkey_load(key, rng, bits+off, len, passwd);+}++int hs_botan_pubkey_load (botan_pubkey_t* key+                         ,const uint8_t bits[], HsInt off, HsInt len){+    return botan_pubkey_load(key, bits+off, len);+}++// Public Key Encryption / Decryption++int hs_botan_pk_op_encrypt(botan_pk_op_encrypt_t op, botan_rng_t rng, uint8_t out[], size_t *out_len, const uint8_t plaintext[], HsInt plaintext_off, HsInt plaintext_len){+    return botan_pk_op_encrypt(op, rng, out, out_len, plaintext+plaintext_off, plaintext_len);+}++int hs_botan_pk_op_decrypt(botan_pk_op_decrypt_t op, uint8_t out[], size_t *out_len, uint8_t ciphertext[], HsInt ciphertext_off, HsInt ciphertext_len){+    return botan_pk_op_decrypt(op, out, out_len, ciphertext+ciphertext_off, ciphertext_len);+}++// Signature Generation & Signature Verification++int hs_botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], HsInt off, HsInt len){+    return botan_pk_op_sign_update(op, in+off, len);+}++int hs_botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], HsInt off, HsInt len){+    return botan_pk_op_verify_update(op, in+off, len);+}++int hs_botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], HsInt off, HsInt len){+    return botan_pk_op_verify_finish(op, sig+off, len);+}++// Key Agreement++int hs_botan_pk_op_key_agreement(botan_pk_op_ka_t op, uint8_t out[], size_t out_len, const uint8_t other_key[], HsInt other_key_off, HsInt other_key_len, const uint8_t salt[], HsInt salt_off, HsInt salt_len){+    // this function will not rewrite out_len+    return botan_pk_op_key_agreement(op, out, &out_len, other_key+other_key_off, other_key_len, salt+salt_off, salt_len);+}++// X.509 Certificates & Certificate Revocation Lists++int hs_botan_x509_cert_load(botan_x509_cert_t *cert_obj, const uint8_t cert[], HsInt cert_off, HsInt cert_len){+    return botan_x509_cert_load(cert_obj, cert+cert_off, cert_len);+}++int hs_botan_x509_cert_verify(botan_x509_cert_t cert+        , const botan_x509_cert_t *intermediates, HsInt intermediates_len+        , const botan_x509_cert_t *trusted, HsInt trusted_len+        , HsInt required_strength, const char *hostname, uint64_t reference_time){+    int r1;+    int r2 = botan_x509_cert_verify(&r1, cert+            , intermediates, intermediates_len+            , trusted, trusted_len+            , NULL, required_strength, hostname, reference_time);+    if (r2 < 0){+        return r2;+    } else { +        return r1; +    }+}++int hs_botan_x509_cert_verify_with_crl(botan_x509_cert_t cert+        , const botan_x509_cert_t *intermediates, HsInt intermediates_len+        , const botan_x509_cert_t *trusted, HsInt trusted_len+        , const botan_x509_crl_t *crls, HsInt crls_len+        , HsInt required_strength, const char *hostname, uint64_t reference_time){+    int r1;+    int r2 = botan_x509_cert_verify_with_crl(&r1, cert+            , intermediates, intermediates_len+            , trusted, trusted_len+            , crls, crls_len+            , NULL, required_strength, hostname, reference_time);+    if (r2 < 0){+        return r2;+    } else { +        return r1; +    }+}+++int hs_botan_x509_crl_load(botan_x509_crl_t *crl_obj, const uint8_t crl[], HsInt crl_off, HsInt crl_len){+    return botan_x509_crl_load(crl_obj, crl+crl_off, crl_len);+}++// Key wrap++/**+  * Advanced Encryption Standard (AES) Key Wrap Algorithm+  * See `https://tools.ietf.org/html/rfc3394`.+  * Key wrapping as per RFC 3394+*/++int hs_botan_key_unwrap3394(const uint8_t wrapped_key[], HsInt wrapped_key_off, HsInt wrapped_key_len+                           ,const uint8_t kek[], HsInt kek_len+                           ,uint8_t key[], size_t key_len){+    return botan_key_unwrap3394(wrapped_key+wrapped_key_off, wrapped_key_len+                               ,kek, kek_len+                               ,key, &key_len);}++// OTP++int hs_botan_hotp_init(botan_hotp_t* hotp+                      ,const uint8_t key[], HsInt key_off, HsInt key_len+                      ,const char* hash_algo+                      ,HsInt digits){+    return botan_hotp_init(hotp+                          ,key+key_off, key_len+                          ,hash_algo, digits);}++int hs_botan_totp_init(botan_totp_t* totp+                      ,const uint8_t key[], HsInt key_off, HsInt key_len+                      ,const char* hash_algo+                      ,HsInt digits+                      ,HsInt time_step){+    return botan_totp_init(totp, key+key_off, key_len, hash_algo, digits, time_step);}++// FPE++int hs_botan_fpe_fe1_init(botan_fpe_t* fpe, botan_mp_t n,+                       const uint8_t key[], HsInt key_off, HsInt key_len,+                       size_t rounds, uint32_t flags){+return botan_fpe_fe1_init(fpe, n,+                       key+key_off, key_len,+                       rounds, flags);}++int hs_botan_fpe_encrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], HsInt tweak_off, HsInt tweak_len)+{return botan_fpe_encrypt(fpe, x, tweak+tweak_off, tweak_len);}++int hs_botan_fpe_decrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], HsInt tweak_off, HsInt tweak_len)+{return botan_fpe_decrypt(fpe, x, tweak+tweak_off, tweak_len);}++}
+ cbits/hs_botan_streamcipher.cpp view
@@ -0,0 +1,135 @@+#include <botan/ffi.h>+#include <botan/internal/ffi_util.h>+#include <botan/stream_cipher.h>+#include <HsFFI.h>+#include <string.h>++extern "C" {++using namespace Botan_FFI;++// Stream cipher++BOTAN_FFI_DECLARE_STRUCT(botan_stream_cipher_struct, Botan::StreamCipher, 0x9F5B7D34);++typedef struct botan_stream_cipher_struct* botan_stream_cipher_t;++int botan_stream_cipher_init(botan_stream_cipher_t* stream_cipher, const char* stream_cipher_name)+    {+    return ffi_guard_thunk(__func__, [=]() -> int {+        if(stream_cipher == nullptr || stream_cipher_name == nullptr || *stream_cipher_name == 0)+            return BOTAN_FFI_ERROR_NULL_POINTER;++        std::unique_ptr<Botan::StreamCipher> s = Botan::StreamCipher::create(stream_cipher_name);+        if(s == nullptr)+            return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;++        *stream_cipher = new botan_stream_cipher_struct(s.release());+        return BOTAN_FFI_SUCCESS;+        });+    }++int botan_stream_cipher_destroy(botan_stream_cipher_t stream_cipher)+    {+    return BOTAN_FFI_CHECKED_DELETE(stream_cipher);+    }+++int botan_stream_cipher_seek(botan_stream_cipher_t stream_cipher, size_t offset)+    {+    return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.seek(offset); });+    }+++int botan_stream_cipher_clear(botan_stream_cipher_t stream_cipher)+   {+   return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.clear(); });+   }++int botan_stream_cipher_query_keylen(botan_stream_cipher_t stream_cipher,+                                        size_t* out_minimum_keylength,+                                        size_t* out_maximum_keylength)+    {+    return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, {+        *out_minimum_keylength = c.key_spec().minimum_keylength();+        *out_maximum_keylength = c.key_spec().maximum_keylength();+        });+    }++int botan_stream_cipher_get_keyspec(botan_stream_cipher_t stream_cipher,+                                      size_t* out_minimum_keylength,+                                      size_t* out_maximum_keylength,+                                      size_t* out_keylength_modulo)+    {+    return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, {+        if(out_minimum_keylength)+            *out_minimum_keylength = c.key_spec().minimum_keylength();+        if(out_maximum_keylength)+            *out_maximum_keylength = c.key_spec().maximum_keylength();+        if(out_keylength_modulo)+            *out_keylength_modulo = c.key_spec().keylength_multiple();+        });+    }++int botan_stream_cipher_set_key(botan_stream_cipher_t stream_cipher,+                                 const uint8_t* key, size_t key_len)+    {+    return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.set_key(key, key_len); });+    }++int botan_stream_cipher_set_iv(botan_stream_cipher_t stream_cipher,+                                 const uint8_t* iv, size_t iv_len)+    {+    return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.set_iv(iv, iv_len); });+    }++int hs_botan_stream_cipher_set_iv(botan_stream_cipher_t stream_cipher,+                              const uint8_t* iv, HsInt off, HsInt iv_len)+    {+    return botan_stream_cipher_set_iv(stream_cipher, iv+off, iv_len);+    }++int botan_stream_cipher_cipher(botan_stream_cipher_t stream_cipher,+                                const uint8_t input[],+                                uint8_t output[],+                                size_t len)+    {+    return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.cipher(input, output, len); });+    }+++int hs_botan_stream_cipher_cipher(botan_stream_cipher_t stream_cipher,+                                uint8_t output[],+                                const uint8_t input[],+                                HsInt off,+                                HsInt len)+    {+    return botan_stream_cipher_cipher(stream_cipher, input+off, output, len);+    }++int botan_stream_cipher_write_keystream(botan_stream_cipher_t stream_cipher,+                                uint8_t output[],+                                size_t len)+    {+    return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.write_keystream(output, len); });+    }++int botan_stream_cipher_valid_iv_length(botan_stream_cipher_t stream_cipher, size_t nl)+    {+    return BOTAN_FFI_RETURNING(Botan::StreamCipher, stream_cipher, c, {+        return c.valid_iv_length(nl) ? 1 : 0;+        });+    }++int botan_stream_cipher_get_default_iv_length(botan_stream_cipher_t stream_cipher, size_t* nl)+    {+    return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { *nl = c.default_iv_length(); });+    }++int botan_stream_cipher_name(botan_stream_cipher_t stream_cipher, char* name, size_t* name_len)+    {+    return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, {+        return write_str_output(name, name_len, c.name()); });+    }++}
− include/hs_botan.h
@@ -1,149 +0,0 @@-#include <HsFFI.h>-#include <botan/ffi.h>--// Utility Functions-int hs_botan_hex_encode(const uint8_t *x, HsInt x_off, HsInt x_len, char *out);-int hs_botan_hex_encode_lower(const uint8_t *x, HsInt x_off, HsInt x_len, char *out);-HsInt hs_botan_hex_decode(const char* hex_str, HsInt in_off, HsInt in_len, uint8_t* out);--// RNG-int hs_botan_rng_add_entropy(botan_rng_t rng, const uint8_t *seed, HsInt off, HsInt len);--// Block Cipher-int hs_botan_block_cipher_set_key(botan_block_cipher_t bc, const uint8_t *key, HsInt key_off, HsInt key_len);-int hs_botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc-    , const uint8_t in[], HsInt off, uint8_t out[], HsInt blocks);-int hs_botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc-    , const uint8_t in[], HsInt off, uint8_t out[], HsInt blocks);--// Hash-int hs_botan_hash_update(botan_hash_t hash, const uint8_t *input, HsInt off, HsInt len);--// Cipher Mode-int hs_botan_cipher_set_key(botan_cipher_t cipher, const uint8_t* key, HsInt key_off, HsInt key_len);-int hs_botan_cipher_set_associated_data(botan_cipher_t cipher, const uint8_t* ad, HsInt ad_off, HsInt ad_len);-int hs_botan_cipher_start(botan_cipher_t cipher, const uint8_t* nonce, HsInt nonce_off, HsInt nonce_len);-// output buffer length should be at least equal to input length, -// which must be larger than botan_cipher_get_update_granularity-// input_consumed == output_written-HsInt hs_botan_cipher_update(botan_cipher_t cipher_obj,-                               uint8_t* output,-                               const uint8_t* input,-                               HsInt input_off,-                               HsInt input_len);-// output buffer length should be at least equal to following call's result-// botan_cipher_output_length(cipher, input_length, &output_length)-// output_written may differ-HsInt hs_botan_cipher_finish(botan_cipher_t cipher_obj,-                           uint8_t* output,-                           HsInt output_len,-                           const uint8_t* input,-                           HsInt input_off,-                           HsInt input_len);--// Multiple Precision Integers--int hs_botan_mp_to_hex(botan_mp_t mp, char *out, HsInt off);-HsInt hs_botan_mp_to_dec(botan_mp_t mp, char *out, HsInt off);-int hs_botan_mp_set_from_hex(botan_mp_t dest, const char *str, HsInt off, HsInt len);-int hs_botan_mp_set_from_dec(botan_mp_t dest, const char *str, HsInt off, HsInt len);-int hs_botan_mp_from_bin(botan_mp_t mp, const uint8_t* vec, HsInt off, HsInt len);-int hs_botan_mp_to_bin(botan_mp_t mp, uint8_t* vec, HsInt off);--// KDF & PBKDF-int hs_botan_kdf(const char* algo-                ,uint8_t out[], HsInt out_len-                ,const uint8_t passwd[], HsInt passwd_off, HsInt passwd_len-                ,const uint8_t salt[], HsInt salt_off, HsInt salt_len-                ,const uint8_t label[], HsInt label_off, HsInt label_len);--int hs_botan_pwdhash(const char* algo-                    ,HsInt p1, HsInt p2, HsInt p3-                    ,uint8_t out[], HsInt out_len-                    ,const char* passwd, HsInt passwd_len-                    ,const uint8_t salt[], HsInt salt_off, HsInt salt_len);-int hs_botan_pwdhash_timed(const char* algo-                          ,uint32_t msec-                          ,uint8_t out[], HsInt out_len-                          ,const char* passwd, HsInt passwd_len-                          ,const uint8_t salt[], HsInt salt_off, HsInt salt_len);--HsInt hs_botan_bcrypt_generate(uint8_t *out, const char *pwd, HsInt pwd_off, HsInt pwd_len-    , botan_rng_t rng, HsInt work_factor, uint32_t flags);-int hs_botan_bcrypt_is_valid(const char* pwd, HsInt pwd_off, HsInt pwd_len-    , const char* hash, HsInt hash_off, HsInt hash_len);--// MAC--int hs_botan_mac_set_key(botan_mac_t mac, const uint8_t* key, HsInt key_off, HsInt key_len);-int hs_botan_mac_update(botan_mac_t mac, const uint8_t* buf, HsInt off, HsInt len);-int hs_botan_mac_final(botan_mac_t mac, uint8_t out[]);-int hs_botan_mac_clear(botan_mac_t mac);-int hs_botan_mac_name(botan_mac_t mac, char* name, size_t* name_len);-int hs_botan_mac_get_keyspec(botan_mac_t mac,-    size_t* out_minimum_keylength,-    size_t* out_maximum_keylength,-    size_t* out_keylength_modulo);--// Public Key Creation, Import and Export-int hs_botan_privkey_load (botan_privkey_t* key, botan_rng_t rng-                          ,const uint8_t bits[], HsInt off, HsInt len-                          ,const char* passwd);-int hs_botan_pubkey_load (botan_pubkey_t* key-                         ,const uint8_t bits[], HsInt off, HsInt len);-// Public Key Encryption/Decryption-//-int hs_botan_pk_op_encrypt(botan_pk_op_encrypt_t op, botan_rng_t rng, uint8_t out[], HsInt *out_len, const uint8_t plaintext[], HsInt plaintext_off, HsInt plaintext_len);-int hs_botan_pk_op_decrypt(botan_pk_op_decrypt_t op, uint8_t out[], HsInt *out_len, uint8_t ciphertext[], HsInt ciphertext_off, HsInt ciphertext_len);--// Signature Generation & Signature Verification-//-int hs_botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t * in, HsInt off , HsInt len);-int hs_botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t * in, HsInt off, HsInt in_len);-int hs_botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t * sig, HsInt off, HsInt sig_len);--// Key Agreement--int hs_botan_pk_op_key_agreement(botan_pk_op_ka_t op, uint8_t out[], HsInt *out_len, const uint8_t other_key[], HsInt other_key_off, HsInt other_key_len, const uint8_t salt[], HsInt salt_off, HsInt salt_len);--// X.509 Certificates & X.509 Certificate Revocation Lists--int hs_botan_x509_cert_load(botan_x509_cert_t *cert_obj, const uint8_t cert[], HsInt cert_off, HsInt cert_len);-int hs_botan_x509_cert_verify(botan_x509_cert_t cert-        , const botan_x509_cert_t *intermediates, HsInt intermediates_len-        , const botan_x509_cert_t *trusted, HsInt trusted_len-        , HsInt required_strength, const char *hostname, uint64_t reference_time);-int hs_botan_x509_cert_verify_with_crl(botan_x509_cert_t cert-        , const botan_x509_cert_t *intermediates, HsInt intermediates_len-        , const botan_x509_cert_t *trusted, HsInt trusted_len-        , const botan_x509_crl_t *crls, HsInt crls_len-        , HsInt required_strength, const char *hostname, uint64_t reference_time);-int hs_botan_x509_cert_verify_with_certstore_crl(-   botan_x509_cert_t cert,-   const botan_x509_cert_t* intermediates, HsInt intermediates_len,-   const botan_x509_certstore_t store,-   const botan_x509_crl_t* crls, HsInt crls_len,-   size_t required_strength,-   const char* hostname_cstr,-   uint64_t reference_time);--// Key wrap--int hs_botan_key_wrap3394(const uint8_t key[], HsInt key_off, HsInt key_len-                         ,const uint8_t kek[], HsInt kek_off, HsInt kek_len-                         ,uint8_t wrapped_key[], size_t *wrapped_key_len);--int hs_botan_key_unwrap3394(const uint8_t wrapped_key[], HsInt wrapped_key_off, HsInt wrapped_key_len-                           ,const uint8_t kek[], HsInt kek_off, HsInt kek_len-                           ,uint8_t key[], size_t *key_len);-// OTP-int hs_botan_hotp_init(botan_hotp_t* hotp-                      ,const uint8_t key[], HsInt key_off, HsInt key_len-                      ,const char* hash_algo-                      ,HsInt digits);--int hs_botan_totp_init(botan_totp_t* totp-                      ,const uint8_t key[], HsInt key_off, HsInt key_len-                      ,const char* hash_algo-                      ,HsInt digits-                      ,HsInt time_step);
test/Utils.hs view
@@ -14,18 +14,19 @@ import           Z.Data.CBytes      (CBytes) import qualified Z.Data.CBytes      as CB import qualified Z.Data.Vector      as V+import qualified Z.Data.Text        as T import           Prelude            hiding (lines, mod) -- import           Data.IORef  -- | Parse test data vector files. -- See `./third_party/botan/src/tests/data/`.-parseNamedTestVector :: HasCallStack => P.Parser (x, Bool) -> CBytes -> IO [(V.Bytes, x)]+parseNamedTestVector :: HasCallStack => P.Parser x -> CBytes -> IO [(V.Bytes, [x])] parseNamedTestVector p path  = do     withResource (FS.initFile path FS.O_RDONLY FS.DEFAULT_FILE_MODE) $ \ f -> do         bi <- newBufferedInput f         let loopRead = do                 name <- readParser algoName bi-                (lines, eof) <- readParser p bi+                (lines, eof) <- readParser (go []) bi                 if eof                 then return [(name, lines)]                 else do@@ -40,405 +41,151 @@         P.skipWord8         return n --- | Parse @key = value@ or @key  = value@ or @key =@ line-parseKeyValueLine :: V.Bytes -> P.Parser V.Bytes-parseKeyValueLine k1 = do-    P.bytes k1-    P.skipWhile (== SPACE)-    P.word8 EQUAL-    P.skipWhile (== SPACE)-    -- some lines contains trailing spaces, e.g., tls_prf.vec-    V.dropWhileR isSpace <$> P.takeWhile (/= NEWLINE)+    go acc = do+        P.skipWhile (== NEWLINE)+        w <- P.peekMaybe+        case w of+            Nothing -> return (acc, True)+            Just HASH -> skipComment >> go acc+            Just BRACKET_LEFT -> return (acc, False)+            _ -> do+                x <- p+                go (x:acc) -parseHashTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, [(V.Bytes, V.Bytes)])]-parseHashTestVector = parseNamedTestVector (go [])+-- | Parse test data vector files.+-- See `./third_party/botan/src/tests/data/`.+parseTestVector :: HasCallStack => P.Parser x -> CBytes -> IO [x]+parseTestVector p path = do+  withResource (FS.initFile path FS.O_RDONLY FS.DEFAULT_FILE_MODE) $ \f -> do+    bi <- newBufferedInput f+    readParser (h []) bi   where-    go acc = do-      P.skipWhile (\ w -> w /= LETTER_I && w /= BRACKET_LEFT && w /= HASH)-      w <- P.peekMaybe-      case w of-          Nothing -> return (acc, True)-          Just HASH -> do-              P.skipWhile (/= NEWLINE)-              P.skipWord8-              go acc-          Just BRACKET_LEFT -> return (acc, False)-          _ -> do-              i <- parseKeyValueLine "In"-              P.skipWord8-              o <- parseKeyValueLine "Out"-              go ((hexDecode' i, hexDecode' o):acc)+    h acc = do+        P.skipWhile (== NEWLINE)+        c <- P.peekMaybe+        case c of+            Nothing -> pure acc+            Just HASH -> skipComment >> h acc+            _ -> do+                x <- p+                h (x:acc) -parseBlockCipherTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, [(V.Bytes, V.Bytes, V.Bytes)])]-parseBlockCipherTestVector = parseNamedTestVector (go [])++-- | Parse @key = value@ or @key  = value@ or @key =@ line+parseKeyValueLines :: P.Parser [(V.Bytes, V.Bytes)]+parseKeyValueLines = go []   where     go acc = do-      P.skipWhile (\ w -> w /= LETTER_K && w /= BRACKET_LEFT && w /= HASH)-      w <- P.peekMaybe-      case w of-          Nothing -> return (acc, True)-          Just HASH -> do-              P.skipWhile (/= NEWLINE)-              P.skipWord8-              go acc-          Just BRACKET_LEFT -> return (acc, False)-          _ -> do-              key <- parseKeyValueLine "Key"-              P.skipWord8-              i <- parseKeyValueLine "In"-              P.skipWord8-              o <- parseKeyValueLine "Out"-              go ((hexDecode' key, hexDecode' i, hexDecode' o):acc)+        mw <- P.peekMaybe+        case mw of+            Just w ->+                if w == NEWLINE+                then return acc+                else do+                    k <- P.takeWhile (/= SPACE)+                    P.skipWhile (== SPACE)+                    P.word8 EQUAL+                    P.skipWhile (== SPACE)+                    -- some lines contains trailing spaces, e.g., tls_prf.vec+                    v <- V.dropWhileR isSpace <$> P.takeWhile (/= NEWLINE)+                    P.skipWord8 <|> return ()+                    go ((k, v):acc)+            _ -> return acc +skipComment :: P.Parser ()+{-# INLINE skipComment #-}+skipComment = do+    P.skipWhile (/= NEWLINE)+    P.skipWhile (== NEWLINE)++lookupOrEmpty :: [(V.Bytes, V.Bytes)] -> V.Bytes -> V.Bytes+lookupOrEmpty m k = maybe V.empty id (lookup k m)++parseHashTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, [(V.Bytes, V.Bytes)])]+parseHashTestVector = parseNamedTestVector $ do+    m <- parseKeyValueLines+    let i = lookupOrEmpty m "In"+    let o = lookupOrEmpty m "Out"+    return (hexDecode' i, hexDecode' o)++parseBlockCipherTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, [(V.Bytes, V.Bytes, V.Bytes)])]+parseBlockCipherTestVector = parseNamedTestVector $ do+    m <- parseKeyValueLines+    let key = lookupOrEmpty m "Key"+    let i = lookupOrEmpty m "In"+    let o = lookupOrEmpty m "Out"+    return (hexDecode' key, hexDecode' i, hexDecode' o)+ parseCipherModeTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, [(V.Bytes, V.Bytes, V.Bytes, V.Bytes)])]-parseCipherModeTestVector = parseNamedTestVector (go [])-  where-    go acc = do-      P.skipWhile (\ w -> w /= LETTER_K && w /= LETTER_N && w /= BRACKET_LEFT && w /= HASH)-      w <- P.peekMaybe-      case w of-          Nothing -> return (acc, True)-          Just HASH -> do-              P.skipWhile (/= NEWLINE)-              P.skipWord8-              go acc-          Just BRACKET_LEFT -> return (acc, False)-          Just w' -> do-              (key, nonce) <- if w' == LETTER_K-                  then do-                    key <- parseKeyValueLine "Key"-                    P.skipWord8-                    nonce <- parseKeyValueLine "Nonce"-                    P.skipWord8-                    return (key, nonce)-                  else do-                    nonce <- parseKeyValueLine "Nonce"-                    P.skipWord8-                    key <- parseKeyValueLine "Key"-                    P.skipWord8-                    return (key, nonce)-              i <- parseKeyValueLine "In"-              P.skipWord8-              o <- parseKeyValueLine "Out"-              go ((hexDecode' key, hexDecode' nonce, hexDecode' i, hexDecode' o):acc)+parseCipherModeTestVector = parseNamedTestVector $ do+    m <- parseKeyValueLines+    let key = lookupOrEmpty m "Key"+    let nonce = lookupOrEmpty m "Nonce"+    let i = lookupOrEmpty m "In"+    let o = lookupOrEmpty m "Out"+    return (hexDecode' key, hexDecode' nonce, hexDecode' i, hexDecode' o)  parseCipherAEADTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, [(V.Bytes, V.Bytes, V.Bytes, V.Bytes, V.Bytes)])]-parseCipherAEADTestVector = parseNamedTestVector (go [])-  where-    go acc = do-      P.skipWhile (\ w -> w /= LETTER_K && w /= LETTER_N && w /= BRACKET_LEFT && w /= HASH)-      w <- P.peekMaybe-      case w of-          Nothing -> return (acc, True)-          Just HASH -> do-              P.skipWhile (/= NEWLINE)-              P.skipWord8-              go acc-          Just BRACKET_LEFT -> return (acc, False)-          Just w' -> do-              (key, nonce) <- if w' == LETTER_K-                  then do-                    key <- parseKeyValueLine "Key"-                    P.skipWord8-                    nonce <- parseKeyValueLine "Nonce"-                    P.skipWord8-                    return (key, nonce)-                  else do-                    nonce <- parseKeyValueLine "Nonce"-                    P.skipWord8-                    key <- parseKeyValueLine "Key"-                    P.skipWord8-                    return (key, nonce)-              i <- parseKeyValueLine "In"-              P.skipWord8-              ad <- parseKeyValueLine "AD"-              P.skipWord8-              o <- parseKeyValueLine "Out"-              go ((hexDecode' key, hexDecode' nonce, hexDecode' i, hexDecode' ad, hexDecode' o):acc)+parseCipherAEADTestVector = parseNamedTestVector $ do+    m <- parseKeyValueLines+    let key = lookupOrEmpty m "Key"+    let nonce = lookupOrEmpty m "Nonce"+    let i = lookupOrEmpty m "In"+    let o = lookupOrEmpty m "Out"+    let ad = lookupOrEmpty m "AD"+    return (hexDecode' key, hexDecode' nonce, hexDecode' i, hexDecode' ad, hexDecode' o)  --- | Parse test data vector files.--- See `./third_party/botan/src/tests/data/`.-parseTestVector ::-  HasCallStack =>-  -- | (txt, eof)-  P.Parser ([x], Bool) ->-  -- | path-  CBytes ->-  IO [x]-parseTestVector p path = do-  withResource (FS.initFile path FS.O_RDONLY FS.DEFAULT_FILE_MODE) $ \f -> do-    bi <- newBufferedInput f-    let loopRead = do-          (txt, eof) <- readParser p bi-          if eof-            then return txt-            else do-              rest <- loopRead-              return $ txt ++ rest-    loopRead---- | Parse test data vectors of the form:---    -- @Password = @---    -- @Passhash = @--- See `./third_party/botan/src/tests/data/passhash/bcrypt.vec`. parsePasswdHashTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, V.Bytes)]-parsePasswdHashTestVector = parseTestVector $ h []-  where-    h acc = do-      P.skipWhile $ \c ->-        c /= LETTER_P -- goto @Password = @ or @Passhash = @-          && c /= HASH -- deal with comment-      c <- P.peekMaybe-      case c of-        Nothing -> pure (acc, True) -- end of file-        Just HASH -> do-          P.skipWhile (/= NEWLINE) -- line comment-          P.skipWord8 -- skip @\n@-          h acc-        _ -> do-          passwd <- parseKeyValueLine "Password"-          P.skipWord8-          passhash <- parseKeyValueLine "Passhash"-          h $ (hexDecode' passwd, passhash) : acc+parsePasswdHashTestVector = parseTestVector $ do+    m <- parseKeyValueLines+    let passwd = lookupOrEmpty m "Password"+    let passhash = lookupOrEmpty m "Passhash"+    return (hexDecode' passwd, passhash) --- | Parse test data vectors of the form------    -- @Salt == @---    -- @Label == @---    -- @Secret == @---    -- @Output == @------ and (unused) possible------    -- @IKM == @---    -- @XTS == @------ See `./third_party/botan/src/tests/data/kdf/hkdf.vec`. parseKDFTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, [(V.Bytes, V.Bytes, V.Bytes, V.Bytes)])]-parseKDFTestVector = parseNamedTestVector (go [])-  where-    go acc = do-      P.skipWhile (\ w -> w /= LETTER_S-                       && w /= LETTER_L-                       && w /= LETTER_O-                       && w /= LETTER_I-                       && w /= LETTER_X-                       && w /= BRACKET_LEFT && w /= HASH)-      w <- P.peekMaybe-      case w of-          Nothing -> return (acc, True)-          Just HASH -> do-              P.skipWhile (/= NEWLINE)-              P.skipWord8-              go acc-          Just BRACKET_LEFT -> return (acc, False)-          _ -> do-              -- skip possible IKM and XTS-              ikm <- parseKeyValueLine "IKM" <|> pure mempty-              unless (V.null ikm)-                  P.skipWord8-              xts <- parseKeyValueLine "XTS" <|> pure mempty-              unless (V.null xts)-                  P.skipWord8-              salt <- parseKeyValueLine "Salt" <|> pure mempty-              -- and here the salt's value may be empty...: in the format: Salt = <\n>.-              P.peekMaybe >>= \case Just NEWLINE -> P.skipWord8-                                    _            -> return ()-              label <- parseKeyValueLine "Label" <|> pure mempty-              unless (V.null label)-                  P.skipWord8-              secret <- parseKeyValueLine "Secret"-              P.skipWord8-              -- in some test data files the "salt" is placed after "secret", e.g., "kdf1.vec"-              salt <- if V.null salt-                         then do salt <- parseKeyValueLine "Salt" <|> pure mempty-                                 -- and here the salt's value may be empty...: in the format: Salt = <\n>.-                                 P.peekMaybe >>= \case Just NEWLINE -> P.skipWord8-                                                       _            -> return ()-                                 return salt-                         else return salt-              -- in some test data files the "label" is placed after "secret", e.g., "sp800_56a.vec"-              label <- if V.null label-                         then do label <- parseKeyValueLine "Label" <|> pure mempty-                                 unless (V.null label)-                                     P.skipWord8-                                 return label-                         else return label-              o <- parseKeyValueLine "Output"-              go ((hexDecode' salt, hexDecode' label, hexDecode' secret, hexDecode' o):acc)---- | Parse test data vectors of the form------    -- @Salt == @---    -- @Iterations == @---    -- @Passphrase == @---    -- @Output == @------ See `./third_party/botan/src/tests/data/pbkdf/pbkdf1.vec`.-parsePBKDFTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, [(V.Bytes, Int, CBytes, V.Bytes)])]-parsePBKDFTestVector = parseNamedTestVector (go [])-  where-    go acc = do-      P.skipWhile (\ w -> w /= LETTER_S-                       && w /= LETTER_I-                       && w /= LETTER_P-                       && w /= LETTER_O-                       && w /= BRACKET_LEFT && w /= HASH)-      w <- P.peekMaybe-      case w of-          Nothing -> return (acc, True)-          Just HASH -> do-              P.skipWhile (/= NEWLINE)-              P.skipWord8-              go acc-          Just BRACKET_LEFT -> return (acc, False)-          _ -> do-              -- in some cases the "Salt" and "Iterations" is after "Passphrase"-              salt <- parseKeyValueLine "Salt" <|> pure mempty-              P.peekMaybe >>= \case Just NEWLINE -> P.skipWord8-                                    _            -> return ()-              iter <- parseKeyValueLine "Iterations" <|> pure mempty-              P.peekMaybe >>= \case Just NEWLINE -> P.skipWord8-                                    _            -> return ()-              passphrase <- parseKeyValueLine "Passphrase"-              P.skipWord8-              salt <- if V.null salt-                         then do salt <- parseKeyValueLine "Salt" <|> pure mempty-                                 P.peekMaybe >>= \case Just NEWLINE -> P.skipWord8-                                                       _            -> return ()-                                 return salt-                         else return salt-              iter <- if V.null iter-                         then do iter <- parseKeyValueLine "Iterations" <|> pure mempty-                                 P.peekMaybe >>= \case Just NEWLINE -> P.skipWord8-                                                       _            -> return ()-                                 return iter-                         else return iter-              o <- parseKeyValueLine "Output"-              go ( (hexDecode' salt-                 , (fromIntegral . decLoopIntegerFast) iter-                 , CB.fromBytes passphrase-                 , hexDecode' o):acc)+parseKDFTestVector = parseNamedTestVector $ do+    m <- parseKeyValueLines+    let ikm = lookupOrEmpty m "IKM"+    let xts = lookupOrEmpty m "XTS"+    let salt = lookupOrEmpty m "Salt"+    let label = lookupOrEmpty m "Label"+    let secret = lookupOrEmpty m "Secret"+    let o = lookupOrEmpty m "Output"+    return (hexDecode' salt, hexDecode' label, hexDecode' secret, hexDecode' o) +parsePBKDFTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, [(V.Bytes, Int, T.Text, V.Bytes)])]+parsePBKDFTestVector = parseNamedTestVector $ do+    m <- parseKeyValueLines+    let salt = lookupOrEmpty m "Salt"+    let iter = lookupOrEmpty m "Iterations"+    let passphrase = lookupOrEmpty m "Passphrase"+    let o = lookupOrEmpty m "Output"+    return (hexDecode' salt , (fromIntegral . decLoopIntegerFast) iter , T.validate passphrase , hexDecode' o) --- | Parse test data vectors of the form------    -- @IV == @ (possible)---    -- @Key == @---    -- @In == @---    -- @Out == @------ See `./third_party/botan/src/tests/data/mac/cbcmac.vec`. parseMACTestVector :: HasCallStack => CBytes -> IO [(V.Bytes, [(Maybe V.Bytes, V.Bytes, V.Bytes, V.Bytes)])]-parseMACTestVector = parseNamedTestVector (go [])-  where-    go acc = do-      P.skipWhile (\ w -> w /= LETTER_I-                       && w /= LETTER_K-                       && w /= LETTER_O-                       && w /= BRACKET_LEFT && w /= HASH)-      w <- P.peekMaybe-      case w of-          Nothing -> return (acc, True)-          Just HASH -> do-              P.skipWhile (/= NEWLINE)-              P.skipWord8-              go acc-          Just BRACKET_LEFT -> return (acc, False)-          _ -> do-              -- in some cases the "Salt" and "Iterations" is after "Passphrase"-              iv <- optional $ parseKeyValueLine "IV"-              case iv of-                  Just iv' -> unless (V.null iv') P.skipWord8-                  Nothing  -> return ()-              key <- parseKeyValueLine "Key"-              P.skipWord8-              in_ <- parseKeyValueLine "In"-              P.skipWord8-              o <- parseKeyValueLine "Out"-              go ((fmap hexDecode' iv, hexDecode' key, hexDecode' in_, hexDecode' o):acc)--skipComment :: (t -> P.Parser b) -> t -> P.Parser b-{-# INLINE skipComment #-}-skipComment h acc = do-    P.skipWhile (/= NEWLINE)-    P.skipWord8-    h acc+parseMACTestVector = parseNamedTestVector $ do+    m <- parseKeyValueLines+    let iv = lookup "IV" m+    let key = lookupOrEmpty m "Key"+    let in_ = lookupOrEmpty m "In"+    let out = lookupOrEmpty m "Out"+    return (fmap hexDecode' iv, hexDecode' key, hexDecode' in_, hexDecode' out) --- | Parse test data vectors of the form:------    -- @Key == @---    -- @KEK == @---    -- @Output == @------ See `./third_party/botan/src/tests/data/keywrap/rfc3394.vec`. parseKeyWrapVec :: HasCallStack => CBytes -> IO [(V.Bytes, V.Bytes, V.Bytes)]-parseKeyWrapVec = parseTestVector (h [])-  where-    h acc = do-      P.skipWhile (\ w -> w /= LETTER_K && w /= LETTER_O && w /= HASH)-      w <- P.peekMaybe-      case w of-          Nothing -> return (acc, True)-          Just HASH -> skipComment h acc-          _ -> do-            key <- parseKeyValueLine "Key"-            P.skipWord8-            kek <- parseKeyValueLine "KEK"-            P.skipWord8-            o <- parseKeyValueLine "Output"-            h ((hexDecode' key, hexDecode' kek, hexDecode' o) : acc)---- | Parse test data vectors of the form:------    -- [label]         -- [label]---    -- @Key == @       -- @Key == @---    -- @Input == @     -- @Output == @---    -- @Output == @    -- @Input == @------ See `./third_party/botan/src/tests/data/keywrap/`.--- parseNistKeyWrapVec :: HasCallStack => CBytes -> IO [(V.Bytes ,[(V.Bytes, V.Bytes, V.Bytes)])]--- parseNistKeyWrapVec = parseNamedTestVector (h [])---     where---       h acc = do---         P.skipWhile $ \ w -> w /= LETTER_K---                           && w /= LETTER_O---                           && w /= BRACKET_LEFT && w /= HASH---         w <- P.peekMaybe---         case w of---           Nothing -> return (acc, True)---           Just HASH -> skipComment h acc---           Just BRACE_LEFT -> return (acc, False)---           _ -> do---             key <- parseKeyValueLine "Key"---             P.skipWord8---             resTag <- liftIO $ newIORef False---             res0 <- parseKeyValueLine "Input" <* (liftIO $ writeIORef resTag True) <|> parseKeyValueLine "Output"---             P.skipWord8---             res1 <- parseKeyValueLine "Input" <|> parseKeyValueLine "Output"---             resTag' <- liftIO $ readIORef resTag---             let (i, o) = if resTag' then (res0, res1) else (res1, res0)---             h ((hexDecode' key, hexDecode' i, hexDecode' o) : acc)+parseKeyWrapVec = parseTestVector $ do+    m <- parseKeyValueLines+    let key = lookupOrEmpty m "Key"+    let kek = lookupOrEmpty m "KEK"+    let o = lookupOrEmpty m "Output"+    return (hexDecode' key, hexDecode' kek, hexDecode' o)  parseFPEVec :: HasCallStack => CBytes -> IO [(V.Bytes, V.Bytes, V.Bytes, V.Bytes, V.Bytes)]-parseFPEVec = parseTestVector (h [])-    where-        h acc = do-            P.skipWhile $ \ w -> w /= LETTER_M -- Mod-                              && w /= LETTER_I -- In-                              && w /= LETTER_O -- Out-                              && w /= LETTER_K -- Key-                              && w /= LETTER_T -- Tweak-                              && w /= HASH-            w <- P.peekMaybe-            case w of-                Nothing -> return (acc, True)-                Just HASH -> skipComment h acc-                _ -> do-                    mod   <- parseKeyValueLine "Mod"   <* P.skipWord8-                    i     <- parseKeyValueLine "In"    <* P.skipWord8-                    o     <- parseKeyValueLine "Out"   <* P.skipWord8-                    key   <- parseKeyValueLine "Key"   <* P.skipWord8-                    tweak <- parseKeyValueLine "Tweak" <* P.skipWord8-                    h ((mod, i, o, hexDecode' key, hexDecode' tweak) : acc)+parseFPEVec = parseTestVector $ do+    m <- parseKeyValueLines+    let mod = lookupOrEmpty m "Mod"+    let i = lookupOrEmpty m "In"+    let o = lookupOrEmpty m "Out"+    let key = lookupOrEmpty m "Key"+    let tweak = lookupOrEmpty m "Tweak"+    return (mod, i, o, hexDecode' key, hexDecode' tweak)
test/Z/Crypto/CipherSpec.hs view
@@ -14,6 +14,7 @@ import qualified Z.Data.Text        as T import           Z.Crypto.Cipher import           Z.Crypto.Hash+import           Z.Crypto.SafeMem import           Utils  spec :: Spec@@ -54,7 +55,10 @@                 it (T.unpack $ T.validate algoName) $ do                     tvMap <- parseBlockCipherTestVector =<< "./third_party/botan/src/tests/data/block/" `FS.join` file                     tvs <- unwrap' "ENOTFOUND" "no algo founded" $ lookup algoName tvMap-                    forM_ tvs $ \ (key, i, o) -> do+                    forM_ tvs $ \ (key0, i, o) -> do++                        key <- unsafeSecretFromBytes key0+                         c <- newBlockCipher cipherType                         setBlockCipherKey c key                         o' <- encryptBlocks c i (V.length i `quot` blockCipherSize c)@@ -79,18 +83,18 @@             , ("cbc.vec", "AES-256/CBC/NoPadding", CBC_NoPadding AES256)             , ("cbc.vec", "AES-128/CBC/CTS", CBC_CTS AES128)             , ("cbc.vec", "ARIA-256/CBC/NoPadding", CBC_NoPadding ARIA256)-            , ("cfb.vec", "DES/CFB", CFB DES 0)-            , ("cfb.vec", "DES/CFB(32)", CFB DES 32)-            , ("cfb.vec", "DES/CFB(16)", CFB DES 16)-            , ("cfb.vec", "DES/CFB(8)", CFB DES 8)-            , ("cfb.vec", "TripleDES/CFB", CFB TripleDES 0)-            , ("cfb.vec", "TripleDES/CFB(8)", CFB TripleDES 8)-            , ("cfb.vec", "AES-128/CFB(8)", CFB AES128 8)-            , ("cfb.vec", "AES-192/CFB(8)", CFB AES192 8)-            , ("cfb.vec", "AES-256/CFB(8)", CFB AES256 8)-            , ("cfb.vec", "AES-128/CFB", CFB AES128 0)-            , ("cfb.vec", "AES-192/CFB", CFB AES192 0)-            , ("cfb.vec", "AES-256/CFB", CFB AES256 0)+            , ("cfb.vec", "DES/CFB", CFB DES)+            , ("cfb.vec", "DES/CFB(32)", CFB' DES 32)+            , ("cfb.vec", "DES/CFB(16)", CFB' DES 16)+            , ("cfb.vec", "DES/CFB(8)", CFB' DES 8)+            , ("cfb.vec", "TripleDES/CFB", CFB TripleDES)+            , ("cfb.vec", "TripleDES/CFB(8)", CFB' TripleDES 8)+            , ("cfb.vec", "AES-128/CFB(8)", CFB' AES128 8)+            , ("cfb.vec", "AES-192/CFB(8)", CFB' AES192 8)+            , ("cfb.vec", "AES-256/CFB(8)", CFB' AES256 8)+            , ("cfb.vec", "AES-128/CFB", CFB AES128)+            , ("cfb.vec", "AES-192/CFB", CFB AES192)+            , ("cfb.vec", "AES-256/CFB", CFB AES256)             , ("xts.vec", "AES-128/XTS", XTS AES128)             , ("xts.vec", "AES-256/XTS", XTS AES256)             , ("xts.vec", "Twofish/XTS", XTS Twofish)@@ -102,21 +106,47 @@                 it (T.unpack $ T.validate algoName) $ do                     tvMap <- parseCipherModeTestVector =<< "./third_party/botan/src/tests/data/modes/" `FS.join` file                     tvs <- unwrap' "ENOTFOUND" "no algo founded" $ lookup algoName tvMap-                    forM_ tvs $ \ (key, nonce, i, o) -> do+                    forM_ tvs $ \ (key0, nonce, i, o) -> do +                        key <- unsafeSecretFromBytes key0+                         c <- newCipher cipherType CipherEncrypt                         setCipherKey c key-                        startCipher c nonce                          d <- newCipher cipherType CipherDecrypt                         setCipherKey d key-                        startCipher d nonce -                        o' <- finishCipher c i+                        o' <- runCipher c nonce i ""                         o' @=? o-                        i' <- finishCipher d o++                        i' <- runCipher d nonce o ""                         i' @=? i +    describe "Crypto.Cipher.AEAD" $ do+        forM_+            [ ("ccm.vec", "AES-128/CCM(8,2)", CCM' AES128 8 2)+            , ("chacha20poly1305.vec", "ChaCha20Poly1305", ChaCha20Poly1305)+            ] $ \ (file, algoName, cipherType) ->+                it (T.unpack $ T.validate algoName) $ do+                    tvMap <- parseCipherAEADTestVector =<< "./third_party/botan/src/tests/data/aead/" `FS.join` file+                    tvs <- unwrap' "ENOTFOUND" "no algo founded" $ lookup algoName tvMap+                    forM_ tvs $ \ (key0, nonce, i, ad, o) -> do++                        key <- unsafeSecretFromBytes key0++                        c <- newCipher cipherType CipherEncrypt+                        setCipherKey c key++                        d <- newCipher cipherType CipherDecrypt+                        setCipherKey d key++                        o' <- runCipher c nonce i ad+                        o' @=? o++                        i' <- runCipher d nonce o ad+                        i' @=? i++     describe "Crypto.Cipher.StreamCipher(I)" $ do         forM_             [ ("ctr.vec", "CTR-BE(DES)", CTR_BE DES)@@ -125,17 +155,19 @@                 it (T.unpack $ T.validate algoName) $ do                     tvMap <- parseCipherModeTestVector =<< "./third_party/botan/src/tests/data/modes/" `FS.join` file                     tvs <- unwrap' "ENOTFOUND" "no algo founded" $ lookup algoName tvMap-                    forM_ tvs $ \ (key, nonce, i, o) -> do+                    forM_ tvs $ \ (key0, nonce, i, o) -> do -                        c <- newStreamCipher cipherType CipherEncrypt-                        setCipherKey c key-                        startCipher c nonce+                        key <- unsafeSecretFromBytes key0 -                        d <- newStreamCipher cipherType CipherDecrypt-                        setCipherKey d key-                        startCipher d nonce+                        c <- newStreamCipher cipherType+                        setStreamCipherKey c key+                        setStreamCipherIV c nonce -                        o' <- finishCipher c i+                        d <- newStreamCipher cipherType+                        setStreamCipherKey d key+                        setStreamCipherIV d nonce++                        o' <- runStreamCipher c i                         o' @?= o-                        i' <- finishCipher d o+                        i' <- runStreamCipher d o                         i' @?= i
test/Z/Crypto/HashSpec.hs view
@@ -59,4 +59,5 @@             it (T.unpack $ T.validate algoName) $ do                 tvMap <- parseHashTestVector =<< "./third_party/botan/src/tests/data/hash/" `FS.join` file                 tvs <- unwrap' "ENOTFOUND" "no algo found" $ lookup algoName tvMap-                forM_ tvs $ \ (i, o) -> hash hashType i @?= o+                forM_ tvs $ \ (i, o) -> do+                    hash hashType i @?= ceBytes o
test/Z/Crypto/KDFSpec.hs view
@@ -87,8 +87,9 @@                     tvMap <- parseKDFTestVector =<< "./third_party/botan/src/tests/data/kdf/" `FS.join` file                     tvs <- unwrap' "ENOTFOUND" "no algo founded" $ lookup algoName tvMap                     forM_ tvs $ \ (salt, label, secret, o) -> do-                        o' <- kdf kdfType (V.length o) secret salt label-                        o' @?= o+                        secret' <- unsafeSecretFromBytes secret+                        o' <- kdf kdfType (V.length o) secret' salt label+                        unsafeSecretToBytes o' >>= (@?= o)      describe "Crypto.KDF.PBKDF" $ do         forM_@@ -105,5 +106,5 @@                     tvMap <- parsePBKDFTestVector =<< "./third_party/botan/src/tests/data/pbkdf/" `FS.join` file                     tvs <- unwrap' "ENOTFOUND" "no algo founded" $ lookup algoName tvMap                     forM_ tvs $ \ (salt, iterations, passphrase, o) -> do-                        o' <- pbkdf (pbkdfType iterations) (V.length o) passphrase salt-                        o' @?= o+                        o' <- pbkdf (pbkdfType iterations) (V.length o) (mkPassword passphrase) salt+                        unsafeSecretToBytes o' >>= (@?= o)
test/Z/Crypto/KeyWrapSpec.hs view
@@ -16,6 +16,8 @@     it "RFC 3394" $ do         tvMap <- parseKeyWrapVec "./third_party/botan/src/tests/data/keywrap/rfc3394.vec"         forM_ tvMap $ \ (key, kek, o) -> do-            o'   <- keyWrap key kek-            key' <- keyUnwrap o kek-            (o', key') @=? (o, key)+            key' <- unsafeSecretFromBytes key+            kek' <- unsafeSecretFromBytes kek+            o'   <- keyWrap key' kek'+            key'' <- keyUnwrap o kek'+            (o', key'') @=? (o, key')
test/Z/Crypto/MACSpec.hs view
@@ -51,14 +51,17 @@                 it (T.unpack $ T.validate algoName) $ do                     tvMap <- parseMACTestVector =<< "./third_party/botan/src/tests/data/mac/" `FS.join` file                     tvs <- unwrap' "ENOTFOUND" "no algo founded" $ lookup algoName tvMap-                    forM_ tvs $ \(miv, key, i, o) -> case miv of+                    forM_ tvs $ \(miv, key0, i, o) -> case miv of                         Just _  -> return ()  -- mac->start(nonce) is not supported yet.                         Nothing -> do++                            key <- unsafeSecretFromBytes key0+                             m <- newMAC macType                             setKeyMAC m key                             updateMAC m i                             o' <- finalMAC m-                            o' @?= o+                            o' @?= ceBytes o                              -- test clear                             clearMAC m@@ -68,7 +71,7 @@                             setKeyMAC m key                             updateMAC m i                             o'' <- finalMAC m-                            o'' @=? o+                            o'' @=? ceBytes o                              -- test multiple update                             let ilen = V.length i@@ -79,4 +82,4 @@                                 updateMAC m $ V.slice 1 (ilen - 2) i                                 updateMAC m $ V.slice (ilen - 1) 1 i                                 o''' <- finalMAC m-                                o''' @=? o+                                o''' @=? ceBytes o
test/Z/Crypto/PwdHashSpec.hs view
@@ -3,19 +3,23 @@  module Z.Crypto.PwdHashSpec where -import Control.Monad (forM_)+import Control.Monad import Test.HUnit import Test.Hspec (Spec, describe, it) import Utils (parsePasswdHashTestVector) import Z.Crypto.PwdHash+import qualified Z.Data.Text as T import Z.Crypto.RNG (RNGType (SystemRNG), newRNG)  spec :: Spec spec = describe "Crypto.PwdHash" $ do     it "Bcrypt" $ do         tvMap <- parsePasswdHashTestVector "./third_party/botan/src/tests/data/passhash/bcrypt.vec"-        forM_ tvMap $ \ (passwd, passhash) -> do-            rng <- newRNG SystemRNG-            ret <- genBcrypt passwd rng 8-            b <- validBcrypt passwd passhash-            b @?= True+        forM_ tvMap $ \ (passwd, passhash) ->+            case mkPasswordMaybe =<< T.validateMaybe passwd of+                Just pwd -> do+                    rng <- newRNG SystemRNG+                    ret <- genBcrypt pwd rng 8+                    b <- validBcrypt pwd passhash+                    b @?= True+                _ -> return ()
third_party/botan/botan_all.cpp view

file too large to diff

third_party/botan/configure.py view
@@ -333,6 +333,9 @@     target_group.add_option('--ldflags', metavar='FLAGS',                             help='set linker flags', default=None) +    target_group.add_option('--extra-libs', metavar='LIBS',+                            help='specify extra libraries to link against', default='')+     target_group.add_option('--ar-command', dest='ar_command', metavar='AR', default=None,                             help='set path to static archive creator') @@ -342,6 +345,9 @@     target_group.add_option('--msvc-runtime', metavar='RT', default=None,                             help='specify MSVC runtime (MT, MD, MTd, MDd)') +    target_group.add_option('--compiler-cache',+                            help='specify a compiler cache to use')+     target_group.add_option('--with-endian', metavar='ORDER', default=None,                             help='override byte order guess') @@ -1988,6 +1994,28 @@             return p         return os.path.join(options.prefix or osinfo.install_root, p) +    def choose_python_exe():+        exe = sys.executable++        if options.os == 'mingw':  # mingw doesn't handle the backslashes in the absolute path well+            return exe.replace('\\', '/')++        return exe++    def choose_cxx_exe():+        cxx = options.compiler_binary or cc.binary_name++        if options.compiler_cache is None:+            return cxx+        else:+            return '%s %s' % (options.compiler_cache, cxx)++    def extra_libs(libs, cc):+        if libs is None:+            return ''++        return ' '.join([(cc.add_lib_option % lib) for lib in libs.split(',') if lib != ''])+     variables = {         'version_major':  Version.major(),         'version_minor':  Version.minor(),@@ -2086,11 +2114,11 @@          'mp_bits': choose_mp_bits(), -        'python_exe': os.path.basename(sys.executable),+        'python_exe': choose_python_exe(),         'python_version': options.python_version,         'install_python_module': not options.no_install_python_module, -        'cxx': (options.compiler_binary or cc.binary_name),+        'cxx': choose_cxx_exe(),         'cxx_abi_flags': cc.mach_abi_link_flags(options),         'linker': cc.linker_name or '$(CXX)',         'make_supports_phony': osinfo.basename != 'windows',@@ -2112,15 +2140,16 @@         'cc_sysroot': sysroot_option(),         'cc_compile_flags': options.cxxflags or cc.cc_compile_flags(options),         'ldflags': options.ldflags or '',+        'extra_libs': extra_libs(options.extra_libs, cc),         'cc_warning_flags': cc.cc_warning_flags(options),         'output_to_exe': cc.output_to_exe,         'cc_macro': cc.macro_name,          'visibility_attribute': cc.gen_visibility_attribute(options), -        'lib_link_cmd': cc.so_link_command_for(osinfo.basename, options) + ' ' + external_link_cmd(),-        'exe_link_cmd': cc.binary_link_command_for(osinfo.basename, options) + ' ' + external_link_cmd(),-        'post_link_cmd': '',+        'lib_link_cmd': cc.so_link_command_for(osinfo.basename, options),+        'exe_link_cmd': cc.binary_link_command_for(osinfo.basename, options),+        'external_link_cmd': external_link_cmd(),          'ar_command': ar_command(),         'ar_options': options.ar_options or cc.ar_options or osinfo.ar_options,@@ -2986,6 +3015,16 @@     # Set default fuzzing lib     if options.build_fuzzers == 'libfuzzer' and options.fuzzer_lib is None:         options.fuzzer_lib = 'Fuzzer'++    if options.ldflags is not None:+        extra_libs = []+        link_to_lib = re.compile('^-l(.*)')+        for flag in options.ldflags.split(' '):+            match = link_to_lib.match(flag)+            if match:+                extra_libs.append(match.group(1))++        options.extra_libs += ','.join(extra_libs)  # Checks user options for consistency # This method DOES NOT change options on behalf of the user but explains
third_party/botan/doc/api_ref/block_cipher.rst view
@@ -304,6 +304,9 @@  Available if ``BOTAN_HAS_NOEKEON`` is defined. +.. warning::+   Support for Noekeon is deprecated and will be removed in a future major release.+ SEED ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
third_party/botan/doc/api_ref/hash.rst view
@@ -154,6 +154,9 @@ An old hash function that is now known to be trivially breakable. It is very fast, and may still be suitable as a (non-cryptographic) checksum. +.. warning::+   Support for MD4 is deprecated and will be removed in a future major release.+ MD5 ^^^^^^^^^ 
third_party/botan/doc/api_ref/kdf.rst view
@@ -83,6 +83,9 @@  Available if ``BOTAN_HAS_X942_PRF`` is defined. +.. warning::+   Support for X9.42 KDF is deprecated and will be removed in a future major release.+ SP800-108 ~~~~~~~~~~ 
third_party/botan/doc/api_ref/psk_db.rst view
@@ -6,7 +6,8 @@ Many applications need to store pre-shared keys (hereafter PSKs) for authentication purposes. -An abstract interface to PSK stores is provided in ``psk_db.h``+An abstract interface to PSK stores, along with some implementations+of same, are provided in ``psk_db.h``  .. cpp:class:: PSK_Database @@ -75,7 +76,8 @@       multiple different master keys with the same underlying storage. Each       master key will be responsible for a subset of the keys. An attacker who       knows one of the keys will be able to tell there are other values-      encrypted under another key.+      encrypted under another key, but will not be able to tell how many other+      master keys are in use.     .. cpp:function:: virtual void kv_set(const std::string& index, const std::string& value) = 0 @@ -96,7 +98,7 @@       non-empty string).  A subclass of ``Encrypted_PSK_Database`` which stores data in a SQL database-is also available. This class is declared in ``psk_db_sql.h``:+is also available.  .. cpp:class:: Encrypted_PSK_Database_SQL : public Encrypted_PSK_Database 
third_party/botan/doc/deprecated.rst view
@@ -59,10 +59,12 @@ This section lists cryptographic functionality which will be removed in a future major release. -- Block ciphers CAST-256, GOST 28147, Kasumi, MISTY1, DESX, and XTEA.+- Block ciphers CAST-256, GOST 28147, Kasumi, MISTY1, DESX, XTEA, Noekeon -- Hash functions GOST 34.11-94 and Tiger+- Hash functions GOST 34.11-94, Tiger, MD4 +- X9.42 KDF+ - DLIES  - MCEIES@@ -256,6 +258,9 @@   ``secqueue.h``,   ``stl_compatibility.h``,   ``uuid.h``,++  Merged into other headers:+  ``alg_id.h``, ``asn1_oid.h``, ``asn1_str.h``, and ``asn1_time.h`` - use ``asn1_obj.h``  Other API deprecations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
third_party/botan/doc/dev_ref/continuous_integration.rst view
@@ -11,11 +11,11 @@ Travis CI ----------- -https://travis-ci.org/randombit/botan+https://travis-ci.com/github/randombit/botan  This is the primary CI, and tests the Linux, macOS, and iOS builds. Among other-things it runs tests using valgrind, cross compilation to different-architectures (currently ARM, PowerPC and MIPS), MinGW build, and a build that+things it runs tests using valgrind, compilation on various architectures+(currently including ARM, PPC64, and S390x), MinGW build, and a build that produces the coverage report.  The Travis configurations is in ``src/scripts/ci/travis.yml``, which executes a@@ -70,6 +70,6 @@  https://github.com/google/oss-fuzz/ -OSS-Fuzz is a distributed fuzzer run by Google. Every night, each library fuzzer-in ``src/fuzzer`` is built and run on many machines with any findings reported-to the developers by email.+OSS-Fuzz is a distributed fuzzer run by Google. Every night, each library fuzzers+in ``src/fuzzer`` are built and run on many machines, with any findings reported+to the developers via email.
third_party/botan/src/build-data/arch/arm32.txt view
@@ -10,6 +10,7 @@  armv7 armv7l+arvm7a armv7-a  armv8l # For AlpineLinux
third_party/botan/src/build-data/arch/arm64.txt view
@@ -5,6 +5,7 @@  <aliases> aarch64+aarch64_be armv8 armv8-a </aliases>
third_party/botan/src/build-data/arch/ppc64.txt view
@@ -13,4 +13,5 @@ <isa_extensions> altivec powercrypto+power9 </isa_extensions>
+ third_party/botan/src/build-data/arch/riscv32.txt view
@@ -0,0 +1,2 @@+family riscv+endian little
third_party/botan/src/build-data/arch/riscv64.txt view
@@ -1,2 +1,3 @@ family riscv endian little+wordsize 64
third_party/botan/src/build-data/botan.doxy.in view
@@ -172,7 +172,10 @@                          BOTAN_HAS_SHACAL2_X86 \                          BOTAN_HAS_SM4_ARMV8 \                          BOTAN_HAS_THREEFISH_512_AVX2 \+                         BOTAN_HAS_GHASH_CLMUL_CPU \+                         BOTAN_HAS_GHASH_CLMUL_VPERM \                          BOTAN_DEPRECATED(msg)= \+                         BOTAN_DEPRECATED_API(msg)= \                          BOTAN_PUBLIC_API(maj,min)= \                          BOTAN_HAS_TLS \                          BOTAN_HAS_BOOST_ASIO \
third_party/botan/src/build-data/cc/clang.txt view
@@ -58,6 +58,9 @@ sha    -> "-msha" altivec -> "-maltivec" +ppc64:powercrypto -> "-mcrypto -mvsx"+ppc64:power9 -> "-mcpu=power9"+ arm64:armv8crypto -> "-march=armv8+crypto"  arm32:neon    -> "-mfpu=neon"
third_party/botan/src/build-data/cc/gcc.txt view
@@ -64,7 +64,8 @@ sha     -> "-msha" altivec -> "-maltivec" -powercrypto -> "-mcrypto"+powercrypto -> "-mcrypto -mvsx"+ppc64:power9 -> "-mcpu=power9"  arm64:armv8crypto -> "" arm64:armv8sm3 -> "-march=armv8.2-a+sm4"
third_party/botan/src/build-data/makefile.in view
@@ -20,8 +20,8 @@  EXE_LINK_CMD   = %{exe_link_cmd} -LIB_LINKS_TO   = %{link_to}-EXE_LINKS_TO   = %{link_to_botan} $(LIB_LINKS_TO)+LIB_LINKS_TO   = %{external_link_cmd} %{link_to}+EXE_LINKS_TO   = %{link_to_botan} $(LIB_LINKS_TO) %{extra_libs}  BUILD_FLAGS    = $(ABI_FLAGS) $(LANG_FLAGS) $(CXXFLAGS) $(WARN_FLAGS) @@ -48,19 +48,19 @@ %{endif}  %{doc_stamp_file}: %{doc_dir}/*.rst %{doc_dir}/api_ref/*.rst %{doc_dir}/dev_ref/*.rst-	$(PYTHON_EXE) $(SCRIPTS_DIR)/build_docs.py --build-dir="%{build_dir}"+	"$(PYTHON_EXE)" "$(SCRIPTS_DIR)/build_docs.py" --build-dir="%{build_dir}"  clean:-	$(PYTHON_EXE) $(SCRIPTS_DIR)/cleanup.py --build-dir="%{build_dir}"+	"$(PYTHON_EXE)" "$(SCRIPTS_DIR)/cleanup.py" --build-dir="%{build_dir}"  distclean:-	$(PYTHON_EXE) $(SCRIPTS_DIR)/cleanup.py --build-dir="%{build_dir}" --distclean+	"$(PYTHON_EXE)" "$(SCRIPTS_DIR)/cleanup.py" --build-dir="%{build_dir}" --distclean  install: %{install_targets}-	$(PYTHON_EXE) $(SCRIPTS_DIR)/install.py --prefix="%{prefix}" --build-dir="%{build_dir}" --bindir=%{bindir} --libdir=%{libdir} --docdir=%{docdir} --includedir=%{includedir}+	"$(PYTHON_EXE)" "$(SCRIPTS_DIR)/install.py" --prefix="%{prefix}" --build-dir="%{build_dir}" --bindir="%{bindir}" --libdir="%{libdir}" --docdir="%{docdir}" --includedir="%{includedir}"  check: tests-	$(PYTHON_EXE) $(SCRIPTS_DIR)/check.py --build-dir="%{build_dir}"+	"$(PYTHON_EXE)" "$(SCRIPTS_DIR)/check.py" --build-dir="%{build_dir}"  # Object Files LIBOBJS = %{join lib_objs}
third_party/botan/src/build-data/version.txt view
@@ -1,9 +1,9 @@  release_major = 2-release_minor = 17-release_patch = 0+release_minor = 18+release_patch = 1 release_suffix = ''-release_so_abi_rev = 17+release_so_abi_rev = 18  # These are set by the distribution script release_vc_rev = None
third_party/botan/src/cli/psk.cpp view
@@ -8,7 +8,7 @@  #if defined(BOTAN_HAS_PSK_DB) && defined(BOTAN_HAS_SQLITE3) -#include <botan/psk_db_sql.h>+#include <botan/psk_db.h> #include <botan/sqlite3.h> #include <botan/hex.h> 
third_party/botan/src/cli/speed.cpp view
@@ -479,8 +479,6 @@           const std::vector<size_t> buf_sizes = unique_buffer_sizes(get_arg("buf-size")); -         Botan::CPUID::initialize();-          for(std::string cpuid_to_clear : Botan::split_on(get_arg("clear-cpuid"), ','))             {             auto bits = Botan::CPUID::bit_from_string(cpuid_to_clear);@@ -1358,7 +1356,7 @@                y.randomize(rng(), q_bits);                 div_timer->start();-               Botan::divide(x, y, q1, r1);+               Botan::vartime_divide(x, y, q1, r1);                div_timer->stop();                 ct_div_timer->start();@@ -1397,7 +1395,7 @@                x.randomize(rng(), n_bits);                 div_timer->start();-               Botan::divide(x, ten, q1, r1);+               Botan::vartime_divide(x, ten, q1, r1);                div_timer->stop();                 ct_div_timer->start();
+ third_party/botan/src/fuzzer/bn_cmp.cpp view
@@ -0,0 +1,74 @@+/*+* (C) 2021 Jack Lloyd+*+* Botan is released under the Simplified BSD License (see license.txt)+*/++#include "fuzzers.h"++#include <botan/bigint.h>++void fuzz(const uint8_t in[], size_t len)+   {+   const size_t max_bits = 512;++   if(len < 3 || len > 1 + 2*(max_bits/8))+      return;++   const uint8_t signs = in[0];+   const size_t x_len = (len - 1) / 2;++   Botan::BigInt x = Botan::BigInt::decode(in + 1, x_len);+   Botan::BigInt y = Botan::BigInt::decode(in + 1 + x_len, len - x_len - 1);++   if(signs & 1)+      x.flip_sign();+   if(signs & 2)+      y.flip_sign();++   const Botan::BigInt d1 = x - y;+   const Botan::BigInt d2 = y - x;++   FUZZER_ASSERT_TRUE(d1.cmp(d2, false) == 0);++   const bool is_eq = (x == y);+   const bool is_lt = (x < y);+   const bool is_gt = (x > y);+   const bool is_lte = (x <= y);+   const bool is_gte = (x >= y);++   if(is_eq)+      {+      FUZZER_ASSERT_TRUE(d1.is_zero());+      FUZZER_ASSERT_TRUE(d2.is_zero());+      }++   if(is_lte)+      {+      FUZZER_ASSERT_TRUE(is_lt || is_eq);+      }++   if(is_gte)+      {+      FUZZER_ASSERT_TRUE(is_gt || is_eq);+      }++   if(is_lt)+      {+      FUZZER_ASSERT_TRUE(!is_gt);+      FUZZER_ASSERT_TRUE(d1.is_nonzero());+      FUZZER_ASSERT_TRUE(d2.is_nonzero());+      FUZZER_ASSERT_TRUE(d1.is_negative());+      FUZZER_ASSERT_TRUE(d2.is_positive());+      }++   if(is_gt)+      {+      FUZZER_ASSERT_TRUE(!is_lt);+      FUZZER_ASSERT_TRUE(d1.is_nonzero());+      FUZZER_ASSERT_TRUE(d2.is_nonzero());+      FUZZER_ASSERT_TRUE(d1.is_positive());+      FUZZER_ASSERT_TRUE(d2.is_negative());+      }+   }+
third_party/botan/src/fuzzer/x509_dn.cpp view
@@ -5,7 +5,7 @@ */  #include "fuzzers.h"-#include <botan/x509_dn.h>+#include <botan/pkix_types.h> #include <botan/ber_dec.h> #include <botan/hex.h> 
third_party/botan/src/lib/asn1/alg_id.cpp view
@@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/alg_id.h>+#include <botan/asn1_obj.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/oids.h>
third_party/botan/src/lib/asn1/alg_id.h view
@@ -9,59 +9,6 @@ #define BOTAN_ALGORITHM_IDENTIFIER_H_  #include <botan/asn1_obj.h>-#include <botan/asn1_oid.h>-#include <string>-#include <vector>--namespace Botan {--/**-* Algorithm Identifier-*/-class BOTAN_PUBLIC_API(2,0) AlgorithmIdentifier final : public ASN1_Object-   {-   public:-      enum Encoding_Option { USE_NULL_PARAM, USE_EMPTY_PARAM };--      void encode_into(class DER_Encoder&) const override;-      void decode_from(class BER_Decoder&) override;--      AlgorithmIdentifier() = default;--      AlgorithmIdentifier(const OID& oid, Encoding_Option enc);-      AlgorithmIdentifier(const std::string& oid_name, Encoding_Option enc);--      AlgorithmIdentifier(const OID& oid, const std::vector<uint8_t>& params);-      AlgorithmIdentifier(const std::string& oid_name, const std::vector<uint8_t>& params);--      const OID& get_oid() const { return oid; }-      const std::vector<uint8_t>& get_parameters() const { return parameters; }--      bool parameters_are_null() const;-      bool parameters_are_empty() const { return parameters.empty(); }--      bool parameters_are_null_or_empty() const-         {-         return parameters_are_empty() || parameters_are_null();-         }--   BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES:-      /*-      * These values are public for historical reasons, but in a future release-      * they will be made private. Do not access them.-      */-      OID oid;-      std::vector<uint8_t> parameters;-   };--/*-* Comparison Operations-*/-bool BOTAN_PUBLIC_API(2,0) operator==(const AlgorithmIdentifier&,-                                      const AlgorithmIdentifier&);-bool BOTAN_PUBLIC_API(2,0) operator!=(const AlgorithmIdentifier&,-                                      const AlgorithmIdentifier&);--}+BOTAN_DEPRECATED_HEADER(alg_id.h)  #endif
− third_party/botan/src/lib/asn1/asn1_attribute.cpp
@@ -1,58 +0,0 @@-/*-* Attribute-* (C) 1999-2007 Jack Lloyd-*-* Botan is released under the Simplified BSD License (see license.txt)-*/--#include <botan/asn1_attribute.h>-#include <botan/der_enc.h>-#include <botan/ber_dec.h>-#include <botan/oids.h>--namespace Botan {--/*-* Create an Attribute-*/-Attribute::Attribute(const OID& attr_oid, const std::vector<uint8_t>& attr_value) :-   oid(attr_oid),-   parameters(attr_value)-   {}--/*-* Create an Attribute-*/-Attribute::Attribute(const std::string& attr_oid,-                     const std::vector<uint8_t>& attr_value) :-   oid(OID::from_string(attr_oid)),-   parameters(attr_value)-   {}--/*-* DER encode a Attribute-*/-void Attribute::encode_into(DER_Encoder& codec) const-   {-   codec.start_cons(SEQUENCE)-      .encode(oid)-      .start_cons(SET)-         .raw_bytes(parameters)-      .end_cons()-   .end_cons();-   }--/*-* Decode a BER encoded Attribute-*/-void Attribute::decode_from(BER_Decoder& codec)-   {-   codec.start_cons(SEQUENCE)-      .decode(oid)-      .start_cons(SET)-         .raw_bytes(parameters)-      .end_cons()-   .end_cons();-   }--}
− third_party/botan/src/lib/asn1/asn1_attribute.h
@@ -1,45 +0,0 @@-/*-* ASN.1 Attribute-* (C) 1999-2007,2012 Jack Lloyd-*-* Botan is released under the Simplified BSD License (see license.txt)-*/--#ifndef BOTAN_ASN1_ATTRIBUTE_H_-#define BOTAN_ASN1_ATTRIBUTE_H_--#include <botan/asn1_obj.h>-#include <botan/asn1_oid.h>-#include <vector>--namespace Botan {--/**-* Attribute-*/-class BOTAN_PUBLIC_API(2,0) Attribute final : public ASN1_Object-   {-   public:-      void encode_into(class DER_Encoder& to) const override;-      void decode_from(class BER_Decoder& from) override;--      Attribute() = default;-      Attribute(const OID&, const std::vector<uint8_t>&);-      Attribute(const std::string&, const std::vector<uint8_t>&);--      const OID& get_oid() const { return oid; }--      const std::vector<uint8_t>& get_parameters() const { return parameters; }--   BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES:-      /*-      * These values are public for historical reasons, but in a future release-      * they will be made private. Do not access them.-      */-      OID oid;-      std::vector<uint8_t> parameters;-   };--}--#endif
third_party/botan/src/lib/asn1/asn1_obj.h view
@@ -1,15 +1,17 @@ /*-* ASN.1 Internals-* (C) 1999-2007,2018 Jack Lloyd+* (C) 1999-2007,2018,2020 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ -#ifndef BOTAN_ASN1_H_-#define BOTAN_ASN1_H_+#ifndef BOTAN_ASN1_OBJECT_TYPES_H_+#define BOTAN_ASN1_OBJECT_TYPES_H_  #include <botan/secmem.h> #include <botan/exceptn.h>+#include <vector>+#include <string>+#include <chrono>  namespace Botan { @@ -184,6 +186,289 @@       BER_Bad_Tag(const std::string& msg, ASN1_Tag tag);       BER_Bad_Tag(const std::string& msg, ASN1_Tag tag1, ASN1_Tag tag2);    };++/**+* This class represents ASN.1 object identifiers.+*/+class BOTAN_PUBLIC_API(2,0) OID final : public ASN1_Object+   {+   public:++      /**+      * Create an uninitialied OID object+      */+      explicit OID() {}++      /**+      * Construct an OID from a string.+      * @param str a string in the form "a.b.c" etc., where a,b,c are numbers+      */+      explicit OID(const std::string& str);++      /**+      * Initialize an OID from a sequence of integer values+      */+      explicit OID(std::initializer_list<uint32_t> init) : m_id(init) {}++      /**+      * Initialize an OID from a vector of integer values+      */+      explicit OID(std::vector<uint32_t>&& init) : m_id(init) {}++      /**+      * Construct an OID from a string.+      * @param str a string in the form "a.b.c" etc., where a,b,c are numbers+      *        or any known OID name (for example "RSA" or "X509v3.SubjectKeyIdentifier")+      */+      static OID from_string(const std::string& str);++      void encode_into(class DER_Encoder&) const override;+      void decode_from(class BER_Decoder&) override;++      /**+      * Find out whether this OID is empty+      * @return true is no OID value is set+      */+      bool empty() const { return m_id.empty(); }++      /**+      * Find out whether this OID has a value+      * @return true is this OID has a value+      */+      bool has_value() const { return (m_id.empty() == false); }++      /**+      * Get this OID as list (vector) of its components.+      * @return vector representing this OID+      */+      const std::vector<uint32_t>& get_components() const { return m_id; }++      const std::vector<uint32_t>& get_id() const { return get_components(); }++      /**+      * Get this OID as a string+      * @return string representing this OID+      */+      std::string BOTAN_DEPRECATED("Use OID::to_string") as_string() const+         {+         return this->to_string();+         }++      /**+      * Get this OID as a dotted-decimal string+      * @return string representing this OID+      */+      std::string to_string() const;++      /**+      * If there is a known name associated with this OID, return that.+      * Otherwise return the result of to_string+      */+      std::string to_formatted_string() const;++      /**+      * Compare two OIDs.+      * @return true if they are equal, false otherwise+      */+      bool operator==(const OID& other) const+         {+         return m_id == other.m_id;+         }++      /**+      * Reset this instance to an empty OID.+      */+      void BOTAN_DEPRECATED("Avoid mutation of OIDs") clear() { m_id.clear(); }++      /**+      * Add a component to this OID.+      * @param new_comp the new component to add to the end of this OID+      * @return reference to *this+      */+      BOTAN_DEPRECATED("Avoid mutation of OIDs") OID& operator+=(uint32_t new_comp)+         {+         m_id.push_back(new_comp);+         return (*this);+         }++   private:+      std::vector<uint32_t> m_id;+   };++/**+* Append another component onto the OID.+* @param oid the OID to add the new component to+* @param new_comp the new component to add+*/+OID BOTAN_PUBLIC_API(2,0) operator+(const OID& oid, uint32_t new_comp);++/**+* Compare two OIDs.+* @param a the first OID+* @param b the second OID+* @return true if a is not equal to b+*/+inline bool operator!=(const OID& a, const OID& b)+   {+   return !(a == b);+   }++/**+* Compare two OIDs.+* @param a the first OID+* @param b the second OID+* @return true if a is lexicographically smaller than b+*/+bool BOTAN_PUBLIC_API(2,0) operator<(const OID& a, const OID& b);++/**+* Time (GeneralizedTime/UniversalTime)+*/+class BOTAN_PUBLIC_API(2,0) ASN1_Time final : public ASN1_Object+   {+   public:+      /// DER encode a ASN1_Time+      void encode_into(DER_Encoder&) const override;++      // Decode a BER encoded ASN1_Time+      void decode_from(BER_Decoder&) override;++      /// Return an internal string representation of the time+      std::string to_string() const;++      /// Returns a human friendly string replesentation of no particular formatting+      std::string readable_string() const;++      /// Return if the time has been set somehow+      bool time_is_set() const;++      ///  Compare this time against another+      int32_t cmp(const ASN1_Time& other) const;++      /// Create an invalid ASN1_Time+      ASN1_Time() = default;++      /// Create a ASN1_Time from a time point+      explicit ASN1_Time(const std::chrono::system_clock::time_point& time);++      /// Create an ASN1_Time from string+      ASN1_Time(const std::string& t_spec, ASN1_Tag tag);++      /// Returns a STL timepoint object+      std::chrono::system_clock::time_point to_std_timepoint() const;++      /// Return time since epoch+      uint64_t time_since_epoch() const;++   private:+      void set_to(const std::string& t_spec, ASN1_Tag);+      bool passes_sanity_check() const;++      uint32_t m_year = 0;+      uint32_t m_month = 0;+      uint32_t m_day = 0;+      uint32_t m_hour = 0;+      uint32_t m_minute = 0;+      uint32_t m_second = 0;+      ASN1_Tag m_tag = NO_OBJECT;+   };++/*+* Comparison Operations+*/+bool BOTAN_PUBLIC_API(2,0) operator==(const ASN1_Time&, const ASN1_Time&);+bool BOTAN_PUBLIC_API(2,0) operator!=(const ASN1_Time&, const ASN1_Time&);+bool BOTAN_PUBLIC_API(2,0) operator<=(const ASN1_Time&, const ASN1_Time&);+bool BOTAN_PUBLIC_API(2,0) operator>=(const ASN1_Time&, const ASN1_Time&);+bool BOTAN_PUBLIC_API(2,0) operator<(const ASN1_Time&, const ASN1_Time&);+bool BOTAN_PUBLIC_API(2,0) operator>(const ASN1_Time&, const ASN1_Time&);++typedef ASN1_Time X509_Time;++/**+* ASN.1 string type+* This class normalizes all inputs to a UTF-8 std::string+*/+class BOTAN_PUBLIC_API(2,0) ASN1_String final : public ASN1_Object+   {+   public:+      void encode_into(class DER_Encoder&) const override;+      void decode_from(class BER_Decoder&) override;++      ASN1_Tag tagging() const { return m_tag; }++      const std::string& value() const { return m_utf8_str; }++      size_t size() const { return value().size(); }++      bool empty() const { return m_utf8_str.empty(); }++      std::string BOTAN_DEPRECATED("Use value() to get UTF-8 string instead")+         iso_8859() const;++      /**+      * Return true iff this is a tag for a known string type we can handle.+      * This ignores string types that are not supported, eg teletexString+      */+      static bool is_string_type(ASN1_Tag tag);++      bool operator==(const ASN1_String& other) const+         { return value() == other.value(); }++      explicit ASN1_String(const std::string& utf8 = "");+      ASN1_String(const std::string& utf8, ASN1_Tag tag);+   private:+      std::vector<uint8_t> m_data;+      std::string m_utf8_str;+      ASN1_Tag m_tag;+   };++/**+* Algorithm Identifier+*/+class BOTAN_PUBLIC_API(2,0) AlgorithmIdentifier final : public ASN1_Object+   {+   public:+      enum Encoding_Option { USE_NULL_PARAM, USE_EMPTY_PARAM };++      void encode_into(class DER_Encoder&) const override;+      void decode_from(class BER_Decoder&) override;++      AlgorithmIdentifier() = default;++      AlgorithmIdentifier(const OID& oid, Encoding_Option enc);+      AlgorithmIdentifier(const std::string& oid_name, Encoding_Option enc);++      AlgorithmIdentifier(const OID& oid, const std::vector<uint8_t>& params);+      AlgorithmIdentifier(const std::string& oid_name, const std::vector<uint8_t>& params);++      const OID& get_oid() const { return oid; }+      const std::vector<uint8_t>& get_parameters() const { return parameters; }++      bool parameters_are_null() const;+      bool parameters_are_empty() const { return parameters.empty(); }++      bool parameters_are_null_or_empty() const+         {+         return parameters_are_empty() || parameters_are_null();+         }++   BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES:+      /*+      * These values are public for historical reasons, but in a future release+      * they will be made private. Do not access them.+      */+      OID oid;+      std::vector<uint8_t> parameters;+   };++/*+* Comparison Operations+*/+bool BOTAN_PUBLIC_API(2,0) operator==(const AlgorithmIdentifier&,+                                      const AlgorithmIdentifier&);+bool BOTAN_PUBLIC_API(2,0) operator!=(const AlgorithmIdentifier&,+                                      const AlgorithmIdentifier&);  } 
third_party/botan/src/lib/asn1/asn1_oid.cpp view
@@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/asn1_oid.h>+#include <botan/asn1_obj.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/internal/bit_ops.h>@@ -98,6 +98,7 @@ std::string OID::to_string() const    {    std::ostringstream oss;+   oss.imbue(std::locale("C"));    for(size_t i = 0; i != m_id.size(); ++i)       {       oss << m_id[i];
third_party/botan/src/lib/asn1/asn1_oid.h view
@@ -9,145 +9,6 @@ #define BOTAN_ASN1_OID_H_  #include <botan/asn1_obj.h>-#include <string>-#include <vector>--namespace Botan {--/**-* This class represents ASN.1 object identifiers.-*/-class BOTAN_PUBLIC_API(2,0) OID final : public ASN1_Object-   {-   public:--      /**-      * Create an uninitialied OID object-      */-      explicit OID() {}--      /**-      * Construct an OID from a string.-      * @param str a string in the form "a.b.c" etc., where a,b,c are numbers-      */-      explicit OID(const std::string& str);--      /**-      * Initialize an OID from a sequence of integer values-      */-      explicit OID(std::initializer_list<uint32_t> init) : m_id(init) {}--      /**-      * Initialize an OID from a vector of integer values-      */-      explicit OID(std::vector<uint32_t>&& init) : m_id(init) {}--      /**-      * Construct an OID from a string.-      * @param str a string in the form "a.b.c" etc., where a,b,c are numbers-      *        or any known OID name (for example "RSA" or "X509v3.SubjectKeyIdentifier")-      */-      static OID from_string(const std::string& str);--      void encode_into(class DER_Encoder&) const override;-      void decode_from(class BER_Decoder&) override;--      /**-      * Find out whether this OID is empty-      * @return true is no OID value is set-      */-      bool empty() const { return m_id.empty(); }--      /**-      * Find out whether this OID has a value-      * @return true is this OID has a value-      */-      bool has_value() const { return (m_id.empty() == false); }--      /**-      * Get this OID as list (vector) of its components.-      * @return vector representing this OID-      */-      const std::vector<uint32_t>& get_components() const { return m_id; }--      const std::vector<uint32_t>& get_id() const { return get_components(); }--      /**-      * Get this OID as a string-      * @return string representing this OID-      */-      std::string BOTAN_DEPRECATED("Use OID::to_string") as_string() const-         {-         return this->to_string();-         }--      /**-      * Get this OID as a dotted-decimal string-      * @return string representing this OID-      */-      std::string to_string() const;--      /**-      * If there is a known name associated with this OID, return that.-      * Otherwise return the result of to_string-      */-      std::string to_formatted_string() const;--      /**-      * Compare two OIDs.-      * @return true if they are equal, false otherwise-      */-      bool operator==(const OID& other) const-         {-         return m_id == other.m_id;-         }--      /**-      * Reset this instance to an empty OID.-      */-      void BOTAN_DEPRECATED("Avoid mutation of OIDs") clear() { m_id.clear(); }--      /**-      * Add a component to this OID.-      * @param new_comp the new component to add to the end of this OID-      * @return reference to *this-      */-      BOTAN_DEPRECATED("Avoid mutation of OIDs") OID& operator+=(uint32_t new_comp)-         {-         m_id.push_back(new_comp);-         return (*this);-         }--   private:-      std::vector<uint32_t> m_id;-   };--/**-* Append another component onto the OID.-* @param oid the OID to add the new component to-* @param new_comp the new component to add-*/-OID BOTAN_PUBLIC_API(2,0) operator+(const OID& oid, uint32_t new_comp);--/**-* Compare two OIDs.-* @param a the first OID-* @param b the second OID-* @return true if a is not equal to b-*/-inline bool operator!=(const OID& a, const OID& b)-   {-   return !(a == b);-   }--/**-* Compare two OIDs.-* @param a the first OID-* @param b the second OID-* @return true if a is lexicographically smaller than b-*/-bool BOTAN_PUBLIC_API(2,0) operator<(const OID& a, const OID& b);--}+BOTAN_DEPRECATED_HEADER(asn1_oid.h)  #endif
third_party/botan/src/lib/asn1/asn1_print.cpp view
@@ -9,8 +9,6 @@ #include <botan/hex.h> #include <botan/der_enc.h> #include <botan/ber_dec.h>-#include <botan/asn1_time.h>-#include <botan/asn1_str.h> #include <botan/oids.h> #include <iomanip> #include <sstream>@@ -228,7 +226,7 @@          }       else if(type_tag == UTC_TIME || type_tag == GENERALIZED_TIME)          {-         X509_Time time;+         ASN1_Time time;          data.decode(time);          output << format(type_tag, class_tag, level, length, time.readable_string());          }
third_party/botan/src/lib/asn1/asn1_str.cpp view
@@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/asn1_str.h>+#include <botan/asn1_obj.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/charset.h>
third_party/botan/src/lib/asn1/asn1_str.h view
@@ -9,47 +9,6 @@ #define BOTAN_ASN1_STRING_H_  #include <botan/asn1_obj.h>--namespace Botan {--/**-* ASN.1 string type-* This class normalizes all inputs to a UTF-8 std::string-*/-class BOTAN_PUBLIC_API(2,0) ASN1_String final : public ASN1_Object-   {-   public:-      void encode_into(class DER_Encoder&) const override;-      void decode_from(class BER_Decoder&) override;--      ASN1_Tag tagging() const { return m_tag; }--      const std::string& value() const { return m_utf8_str; }--      size_t size() const { return value().size(); }--      bool empty() const { return m_utf8_str.empty(); }--      std::string BOTAN_DEPRECATED("Use value() to get UTF-8 string instead")-         iso_8859() const;--      /**-      * Return true iff this is a tag for a known string type we can handle.-      * This ignores string types that are not supported, eg teletexString-      */-      static bool is_string_type(ASN1_Tag tag);--      bool operator==(const ASN1_String& other) const-         { return value() == other.value(); }--      explicit ASN1_String(const std::string& utf8 = "");-      ASN1_String(const std::string& utf8, ASN1_Tag tag);-   private:-      std::vector<uint8_t> m_data;-      std::string m_utf8_str;-      ASN1_Tag m_tag;-   };--}+BOTAN_DEPRECATED_HEADER(asn1_str.h)  #endif
third_party/botan/src/lib/asn1/asn1_time.cpp view
@@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/asn1_time.h>+#include <botan/asn1_obj.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/exceptn.h>@@ -16,7 +16,7 @@  namespace Botan { -X509_Time::X509_Time(const std::chrono::system_clock::time_point& time)+ASN1_Time::ASN1_Time(const std::chrono::system_clock::time_point& time)    {    calendar_point cal = calendar_value(time); @@ -30,37 +30,37 @@    m_tag = (m_year >= 2050) ? GENERALIZED_TIME : UTC_TIME;    } -X509_Time::X509_Time(const std::string& t_spec, ASN1_Tag tag)+ASN1_Time::ASN1_Time(const std::string& t_spec, ASN1_Tag tag)    {    set_to(t_spec, tag);    } -void X509_Time::encode_into(DER_Encoder& der) const+void ASN1_Time::encode_into(DER_Encoder& der) const    {    BOTAN_ARG_CHECK(m_tag == UTC_TIME || m_tag == GENERALIZED_TIME,-                   "X509_Time: Bad encoding tag");+                   "ASN1_Time: Bad encoding tag");     der.add_object(m_tag, UNIVERSAL, to_string());    } -void X509_Time::decode_from(BER_Decoder& source)+void ASN1_Time::decode_from(BER_Decoder& source)    {    BER_Object ber_time = source.get_next_object();     set_to(ASN1::to_string(ber_time), ber_time.type());    } -std::string X509_Time::to_string() const+std::string ASN1_Time::to_string() const    {    if(time_is_set() == false)-      throw Invalid_State("X509_Time::to_string: No time set");+      throw Invalid_State("ASN1_Time::to_string: No time set");     uint32_t full_year = m_year;     if(m_tag == UTC_TIME)       {       if(m_year < 1950 || m_year >= 2050)-         throw Encoding_Error("X509_Time: The time " + readable_string() ++         throw Encoding_Error("ASN1_Time: The time " + readable_string() +                               " cannot be encoded as a UTCTime");        full_year = (m_year >= 2000) ? (m_year - 2000) : (m_year - 1900);@@ -90,10 +90,10 @@    return repr;    } -std::string X509_Time::readable_string() const+std::string ASN1_Time::readable_string() const    {    if(time_is_set() == false)-      throw Invalid_State("X509_Time::readable_string: No time set");+      throw Invalid_State("ASN1_Time::readable_string: No time set");     // desired format: "%04d/%02d/%02d %02d:%02d:%02d UTC"    std::stringstream output;@@ -110,15 +110,15 @@    return output.str();    } -bool X509_Time::time_is_set() const+bool ASN1_Time::time_is_set() const    {    return (m_year != 0);    } -int32_t X509_Time::cmp(const X509_Time& other) const+int32_t ASN1_Time::cmp(const ASN1_Time& other) const    {    if(time_is_set() == false)-      throw Invalid_State("X509_Time::cmp: No time set");+      throw Invalid_State("ASN1_Time::cmp: No time set");     const int32_t EARLIER = -1, LATER = 1, SAME_TIME = 0; @@ -138,7 +138,7 @@    return SAME_TIME;    } -void X509_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag)+void ASN1_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag)    {    if(spec_tag == UTC_OR_GENERALIZED_TIME)       {@@ -215,7 +215,7 @@ /* * Do a general sanity check on the time */-bool X509_Time::passes_sanity_check() const+bool ASN1_Time::passes_sanity_check() const    {    // AppVeyor's trust store includes a cert with expiration date in 3016 ...    if(m_year < 1950 || m_year > 3100)@@ -258,33 +258,33 @@    return true;    } -std::chrono::system_clock::time_point X509_Time::to_std_timepoint() const+std::chrono::system_clock::time_point ASN1_Time::to_std_timepoint() const    {    return calendar_point(m_year, m_month, m_day, m_hour, m_minute, m_second).to_std_timepoint();    } -uint64_t X509_Time::time_since_epoch() const+uint64_t ASN1_Time::time_since_epoch() const    {    auto tp = this->to_std_timepoint();    return std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch()).count();    }  /*-* Compare two X509_Times for in various ways+* Compare two ASN1_Times for in various ways */-bool operator==(const X509_Time& t1, const X509_Time& t2)+bool operator==(const ASN1_Time& t1, const ASN1_Time& t2)    { return (t1.cmp(t2) == 0); }-bool operator!=(const X509_Time& t1, const X509_Time& t2)+bool operator!=(const ASN1_Time& t1, const ASN1_Time& t2)    { return (t1.cmp(t2) != 0); } -bool operator<=(const X509_Time& t1, const X509_Time& t2)+bool operator<=(const ASN1_Time& t1, const ASN1_Time& t2)    { return (t1.cmp(t2) <= 0); }-bool operator>=(const X509_Time& t1, const X509_Time& t2)+bool operator>=(const ASN1_Time& t1, const ASN1_Time& t2)    { return (t1.cmp(t2) >= 0); } -bool operator<(const X509_Time& t1, const X509_Time& t2)+bool operator<(const ASN1_Time& t1, const ASN1_Time& t2)    { return (t1.cmp(t2) < 0); }-bool operator>(const X509_Time& t1, const X509_Time& t2)+bool operator>(const ASN1_Time& t1, const ASN1_Time& t2)    { return (t1.cmp(t2) > 0); }  }
third_party/botan/src/lib/asn1/asn1_time.h view
@@ -9,74 +9,6 @@ #define BOTAN_ASN1_TIME_H_  #include <botan/asn1_obj.h>-#include <chrono>--namespace Botan {--/**-* X.509 Time-*/-class BOTAN_PUBLIC_API(2,0) X509_Time final : public ASN1_Object-   {-   public:-      /// DER encode a X509_Time-      void encode_into(DER_Encoder&) const override;--      // Decode a BER encoded X509_Time-      void decode_from(BER_Decoder&) override;--      /// Return an internal string representation of the time-      std::string to_string() const;--      /// Returns a human friendly string replesentation of no particular formatting-      std::string readable_string() const;--      /// Return if the time has been set somehow-      bool time_is_set() const;--      ///  Compare this time against another-      int32_t cmp(const X509_Time& other) const;--      /// Create an invalid X509_Time-      X509_Time() = default;--      /// Create a X509_Time from a time point-      explicit X509_Time(const std::chrono::system_clock::time_point& time);--      /// Create an X509_Time from string-      X509_Time(const std::string& t_spec, ASN1_Tag tag);--      /// Returns a STL timepoint object-      std::chrono::system_clock::time_point to_std_timepoint() const;--      /// Return time since epoch-      uint64_t time_since_epoch() const;--   private:-      void set_to(const std::string& t_spec, ASN1_Tag);-      bool passes_sanity_check() const;--      uint32_t m_year = 0;-      uint32_t m_month = 0;-      uint32_t m_day = 0;-      uint32_t m_hour = 0;-      uint32_t m_minute = 0;-      uint32_t m_second = 0;-      ASN1_Tag m_tag = NO_OBJECT;-   };--/*-* Comparison Operations-*/-bool BOTAN_PUBLIC_API(2,0) operator==(const X509_Time&, const X509_Time&);-bool BOTAN_PUBLIC_API(2,0) operator!=(const X509_Time&, const X509_Time&);-bool BOTAN_PUBLIC_API(2,0) operator<=(const X509_Time&, const X509_Time&);-bool BOTAN_PUBLIC_API(2,0) operator>=(const X509_Time&, const X509_Time&);-bool BOTAN_PUBLIC_API(2,0) operator<(const X509_Time&, const X509_Time&);-bool BOTAN_PUBLIC_API(2,0) operator>(const X509_Time&, const X509_Time&);--typedef X509_Time ASN1_Time;--}+BOTAN_DEPRECATED_HEADER(asn1_time.h)  #endif
third_party/botan/src/lib/asn1/ber_dec.h view
@@ -132,7 +132,7 @@                                      ASN1_Tag type_tag,                                      ASN1_Tag class_tag = CONTEXT_SPECIFIC)          {-         static_assert(std::is_pod<T>::value, "Type must be POD");+         static_assert(std::is_standard_layout<T>::value && std::is_trivial<T>::value, "Type must be POD");           BER_Object obj = get_next_object();          obj.assert_is_a(type_tag, class_tag);
third_party/botan/src/lib/asn1/der_enc.h view
@@ -15,7 +15,6 @@ namespace Botan {  class BigInt;-class ASN1_Object;  /** * General DER Encoding Object
third_party/botan/src/lib/asn1/oids.h view
@@ -8,7 +8,7 @@ #ifndef BOTAN_OIDS_H_ #define BOTAN_OIDS_H_ -#include <botan/asn1_oid.h>+#include <botan/asn1_obj.h> #include <unordered_map>  namespace Botan {
third_party/botan/src/lib/base/key_spec.h view
@@ -8,93 +8,7 @@ #ifndef BOTAN_KEY_LEN_SPECIFICATION_H_ #define BOTAN_KEY_LEN_SPECIFICATION_H_ -#include <botan/types.h>--namespace Botan {--/**-* Represents the length requirements on an algorithm key-*/-class BOTAN_PUBLIC_API(2,0) Key_Length_Specification final-   {-   public:-      /**-      * Constructor for fixed length keys-      * @param keylen the supported key length-      */-      explicit Key_Length_Specification(size_t keylen) :-         m_min_keylen(keylen),-         m_max_keylen(keylen),-         m_keylen_mod(1)-         {-         }--      /**-      * Constructor for variable length keys-      * @param min_k the smallest supported key length-      * @param max_k the largest supported key length-      * @param k_mod the number of bytes the key must be a multiple of-      */-      Key_Length_Specification(size_t min_k,-                               size_t max_k,-                               size_t k_mod = 1) :-         m_min_keylen(min_k),-         m_max_keylen(max_k ? max_k : min_k),-         m_keylen_mod(k_mod)-         {-         }--      /**-      * @param length is a key length in bytes-      * @return true iff this length is a valid length for this algo-      */-      bool valid_keylength(size_t length) const-         {-         return ((length >= m_min_keylen) &&-                 (length <= m_max_keylen) &&-                 (length % m_keylen_mod == 0));-         }--      /**-      * @return minimum key length in bytes-      */-      size_t minimum_keylength() const-         {-         return m_min_keylen;-         }--      /**-      * @return maximum key length in bytes-      */-      size_t maximum_keylength() const-         {-         return m_max_keylen;-         }--      /**-      * @return key length multiple in bytes-      */-      size_t keylength_multiple() const-         {-         return m_keylen_mod;-         }--      /*-      * Multiplies all length requirements with the given factor-      * @param n the multiplication factor-      * @return a key length specification multiplied by the factor-      */-      Key_Length_Specification multiple(size_t n) const-         {-         return Key_Length_Specification(n * m_min_keylen,-                                         n * m_max_keylen,-                                         n * m_keylen_mod);-         }--   private:-      size_t m_min_keylen, m_max_keylen, m_keylen_mod;-   };--}+#include <botan/sym_algo.h>+BOTAN_DEPRECATED_HEADER(key_spec.h)  #endif
third_party/botan/src/lib/base/scan_name.cpp view
@@ -32,9 +32,12 @@          }       else if(name[i].first < level)          {-         output += ")," + name[i].second;-         --paren_depth;+         for (size_t j = name[i].first; j < level; j++) {+            output += ")";+            --paren_depth;          }+         output += "," + name[i].second;+         }       else          {          if(output[output.size() - 1] != '(')@@ -58,7 +61,7 @@    }  SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg_name(), m_args(), m_mode_info()-   {+   {     if(algo_spec.size() == 0)       throw Invalid_Argument("Expected algorithm name, got empty string"); 
third_party/botan/src/lib/base/secmem.h view
@@ -71,38 +71,7 @@ template<typename T> std::vector<T> unlock(const secure_vector<T>& in)    {-   std::vector<T> out(in.size());-   copy_mem(out.data(), in.data(), in.size());-   return out;-   }--template<typename T, typename Alloc>-size_t buffer_insert(std::vector<T, Alloc>& buf,-                     size_t buf_offset,-                     const T input[],-                     size_t input_length)-   {-   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());-   const size_t to_copy = std::min(input_length, buf.size() - buf_offset);-   if(to_copy > 0)-      {-      copy_mem(&buf[buf_offset], input, to_copy);-      }-   return to_copy;-   }--template<typename T, typename Alloc, typename Alloc2>-size_t buffer_insert(std::vector<T, Alloc>& buf,-                     size_t buf_offset,-                     const std::vector<T, Alloc2>& input)-   {-   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());-   const size_t to_copy = std::min(input.size(), buf.size() - buf_offset);-   if(to_copy > 0)-      {-      copy_mem(&buf[buf_offset], input.data(), to_copy);-      }-   return to_copy;+   return std::vector<T>(in.begin(), in.end());    }  template<typename T, typename Alloc, typename Alloc2>@@ -110,12 +79,8 @@ operator+=(std::vector<T, Alloc>& out,            const std::vector<T, Alloc2>& in)    {-   const size_t copy_offset = out.size();-   out.resize(out.size() + in.size());-   if(in.size() > 0)-      {-      copy_mem(&out[copy_offset], in.data(), in.size());-      }+   out.reserve(out.size() + in.size());+   out.insert(out.end(), in.begin(), in.end());    return out;    } @@ -130,12 +95,8 @@ std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,                                   const std::pair<const T*, L>& in)    {-   const size_t copy_offset = out.size();-   out.resize(out.size() + in.second);-   if(in.second > 0)-      {-      copy_mem(&out[copy_offset], in.first, in.second);-      }+   out.reserve(out.size() + in.second);+   out.insert(out.end(), in.first, in.first + in.second);    return out;    } @@ -143,12 +104,8 @@ std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,                                   const std::pair<T*, L>& in)    {-   const size_t copy_offset = out.size();-   out.resize(out.size() + in.second);-   if(in.second > 0)-      {-      copy_mem(&out[copy_offset], in.first, in.second);-      }+   out.reserve(out.size() + in.second);+   out.insert(out.end(), in.first, in.first + in.second);    return out;    } 
third_party/botan/src/lib/base/sym_algo.h view
@@ -8,11 +8,93 @@ #ifndef BOTAN_SYMMETRIC_ALGORITHM_H_ #define BOTAN_SYMMETRIC_ALGORITHM_H_ -#include <botan/key_spec.h> #include <botan/symkey.h> #include <botan/types.h>  namespace Botan {++/**+* Represents the length requirements on an algorithm key+*/+class BOTAN_PUBLIC_API(2,0) Key_Length_Specification final+   {+   public:+      /**+      * Constructor for fixed length keys+      * @param keylen the supported key length+      */+      explicit Key_Length_Specification(size_t keylen) :+         m_min_keylen(keylen),+         m_max_keylen(keylen),+         m_keylen_mod(1)+         {+         }++      /**+      * Constructor for variable length keys+      * @param min_k the smallest supported key length+      * @param max_k the largest supported key length+      * @param k_mod the number of bytes the key must be a multiple of+      */+      Key_Length_Specification(size_t min_k,+                               size_t max_k,+                               size_t k_mod = 1) :+         m_min_keylen(min_k),+         m_max_keylen(max_k ? max_k : min_k),+         m_keylen_mod(k_mod)+         {+         }++      /**+      * @param length is a key length in bytes+      * @return true iff this length is a valid length for this algo+      */+      bool valid_keylength(size_t length) const+         {+         return ((length >= m_min_keylen) &&+                 (length <= m_max_keylen) &&+                 (length % m_keylen_mod == 0));+         }++      /**+      * @return minimum key length in bytes+      */+      size_t minimum_keylength() const+         {+         return m_min_keylen;+         }++      /**+      * @return maximum key length in bytes+      */+      size_t maximum_keylength() const+         {+         return m_max_keylen;+         }++      /**+      * @return key length multiple in bytes+      */+      size_t keylength_multiple() const+         {+         return m_keylen_mod;+         }++      /*+      * Multiplies all length requirements with the given factor+      * @param n the multiplication factor+      * @return a key length specification multiplied by the factor+      */+      Key_Length_Specification multiple(size_t n) const+         {+         return Key_Length_Specification(n * m_min_keylen,+                                         n * m_max_keylen,+                                         n * m_keylen_mod);+         }++   private:+      size_t m_min_keylen, m_max_keylen, m_keylen_mod;+   };  /** * This class represents a symmetric algorithm object.
third_party/botan/src/lib/block/aria/aria.cpp view
@@ -27,7 +27,7 @@  namespace ARIA_F { -alignas(16)+alignas(64) const uint32_t S1[256]={    0x00636363,0x007c7c7c,0x00777777,0x007b7b7b,0x00f2f2f2,0x006b6b6b,0x006f6f6f,0x00c5c5c5,    0x00303030,0x00010101,0x00676767,0x002b2b2b,0x00fefefe,0x00d7d7d7,0x00ababab,0x00767676,@@ -63,7 +63,7 @@    0x00414141,0x00999999,0x002d2d2d,0x000f0f0f,0x00b0b0b0,0x00545454,0x00bbbbbb,0x00161616 }; -alignas(16)+alignas(64) const uint32_t S2[256]={    0xe200e2e2,0x4e004e4e,0x54005454,0xfc00fcfc,0x94009494,0xc200c2c2,0x4a004a4a,0xcc00cccc,    0x62006262,0x0d000d0d,0x6a006a6a,0x46004646,0x3c003c3c,0x4d004d4d,0x8b008b8b,0xd100d1d1,@@ -99,7 +99,7 @@    0x89008989,0xde00dede,0x71007171,0x1a001a1a,0xaf00afaf,0xba00baba,0xb500b5b5,0x81008181 }; -alignas(16)+alignas(64) const uint32_t X1[256]={    0x52520052,0x09090009,0x6a6a006a,0xd5d500d5,0x30300030,0x36360036,0xa5a500a5,0x38380038,    0xbfbf00bf,0x40400040,0xa3a300a3,0x9e9e009e,0x81810081,0xf3f300f3,0xd7d700d7,0xfbfb00fb,@@ -135,7 +135,7 @@    0xe1e100e1,0x69690069,0x14140014,0x63630063,0x55550055,0x21210021,0x0c0c000c,0x7d7d007d }; -alignas(16)+alignas(64) const uint32_t X2[256]={    0x30303000,0x68686800,0x99999900,0x1b1b1b00,0x87878700,0xb9b9b900,0x21212100,0x78787800,    0x50505000,0x39393900,0xdbdbdb00,0xe1e1e100,0x72727200,0x09090900,0x62626200,0x3c3c3c00,
third_party/botan/src/lib/block/camellia/camellia.cpp view
@@ -13,7 +13,7 @@  namespace { -const uint64_t Camellia_SBOX1[256] = {+alignas(64) const uint64_t Camellia_SBOX1[256] = { 0x7070700070000070, 0x8282820082000082, 0x2C2C2C002C00002C, 0xECECEC00EC0000EC, 0xB3B3B300B30000B3, 0x2727270027000027, 0xC0C0C000C00000C0, 0xE5E5E500E50000E5, 0xE4E4E400E40000E4, 0x8585850085000085, 0x5757570057000057, 0x3535350035000035,@@ -79,7 +79,7 @@ 0x1515150015000015, 0xE3E3E300E30000E3, 0xADADAD00AD0000AD, 0xF4F4F400F40000F4, 0x7777770077000077, 0xC7C7C700C70000C7, 0x8080800080000080, 0x9E9E9E009E00009E }; -const uint64_t Camellia_SBOX2[256] = {+alignas(64) const uint64_t Camellia_SBOX2[256] = { 0x00E0E0E0E0E00000, 0x0005050505050000, 0x0058585858580000, 0x00D9D9D9D9D90000, 0x0067676767670000, 0x004E4E4E4E4E0000, 0x0081818181810000, 0x00CBCBCBCBCB0000, 0x00C9C9C9C9C90000, 0x000B0B0B0B0B0000, 0x00AEAEAEAEAE0000, 0x006A6A6A6A6A0000,@@ -145,7 +145,7 @@ 0x002A2A2A2A2A0000, 0x00C7C7C7C7C70000, 0x005B5B5B5B5B0000, 0x00E9E9E9E9E90000, 0x00EEEEEEEEEE0000, 0x008F8F8F8F8F0000, 0x0001010101010000, 0x003D3D3D3D3D0000 }; -const uint64_t Camellia_SBOX3[256] = {+alignas(64) const uint64_t Camellia_SBOX3[256] = { 0x3800383800383800, 0x4100414100414100, 0x1600161600161600, 0x7600767600767600, 0xD900D9D900D9D900, 0x9300939300939300, 0x6000606000606000, 0xF200F2F200F2F200, 0x7200727200727200, 0xC200C2C200C2C200, 0xAB00ABAB00ABAB00, 0x9A009A9A009A9A00,@@ -211,7 +211,7 @@ 0x8A008A8A008A8A00, 0xF100F1F100F1F100, 0xD600D6D600D6D600, 0x7A007A7A007A7A00, 0xBB00BBBB00BBBB00, 0xE300E3E300E3E300, 0x4000404000404000, 0x4F004F4F004F4F00 }; -const uint64_t Camellia_SBOX4[256] = {+alignas(64) const uint64_t Camellia_SBOX4[256] = { 0x7070007000007070, 0x2C2C002C00002C2C, 0xB3B300B30000B3B3, 0xC0C000C00000C0C0, 0xE4E400E40000E4E4, 0x5757005700005757, 0xEAEA00EA0000EAEA, 0xAEAE00AE0000AEAE, 0x2323002300002323, 0x6B6B006B00006B6B, 0x4545004500004545, 0xA5A500A50000A5A5,@@ -277,7 +277,7 @@ 0x2828002800002828, 0x7B7B007B00007B7B, 0xC9C900C90000C9C9, 0xC1C100C10000C1C1, 0xE3E300E30000E3E3, 0xF4F400F40000F4F4, 0xC7C700C70000C7C7, 0x9E9E009E00009E9E }; -const uint64_t Camellia_SBOX5[256] = {+alignas(64) const uint64_t Camellia_SBOX5[256] = { 0x00E0E0E000E0E0E0, 0x0005050500050505, 0x0058585800585858, 0x00D9D9D900D9D9D9, 0x0067676700676767, 0x004E4E4E004E4E4E, 0x0081818100818181, 0x00CBCBCB00CBCBCB, 0x00C9C9C900C9C9C9, 0x000B0B0B000B0B0B, 0x00AEAEAE00AEAEAE, 0x006A6A6A006A6A6A,@@ -343,7 +343,7 @@ 0x002A2A2A002A2A2A, 0x00C7C7C700C7C7C7, 0x005B5B5B005B5B5B, 0x00E9E9E900E9E9E9, 0x00EEEEEE00EEEEEE, 0x008F8F8F008F8F8F, 0x0001010100010101, 0x003D3D3D003D3D3D }; -const uint64_t Camellia_SBOX6[256] = {+alignas(64) const uint64_t Camellia_SBOX6[256] = { 0x3800383838003838, 0x4100414141004141, 0x1600161616001616, 0x7600767676007676, 0xD900D9D9D900D9D9, 0x9300939393009393, 0x6000606060006060, 0xF200F2F2F200F2F2, 0x7200727272007272, 0xC200C2C2C200C2C2, 0xAB00ABABAB00ABAB, 0x9A009A9A9A009A9A,@@ -409,7 +409,7 @@ 0x8A008A8A8A008A8A, 0xF100F1F1F100F1F1, 0xD600D6D6D600D6D6, 0x7A007A7A7A007A7A, 0xBB00BBBBBB00BBBB, 0xE300E3E3E300E3E3, 0x4000404040004040, 0x4F004F4F4F004F4F }; -const uint64_t Camellia_SBOX7[256] = {+alignas(64) const uint64_t Camellia_SBOX7[256] = { 0x7070007070700070, 0x2C2C002C2C2C002C, 0xB3B300B3B3B300B3, 0xC0C000C0C0C000C0, 0xE4E400E4E4E400E4, 0x5757005757570057, 0xEAEA00EAEAEA00EA, 0xAEAE00AEAEAE00AE, 0x2323002323230023, 0x6B6B006B6B6B006B, 0x4545004545450045, 0xA5A500A5A5A500A5,@@ -475,7 +475,7 @@ 0x2828002828280028, 0x7B7B007B7B7B007B, 0xC9C900C9C9C900C9, 0xC1C100C1C1C100C1, 0xE3E300E3E3E300E3, 0xF4F400F4F4F400F4, 0xC7C700C7C7C700C7, 0x9E9E009E9E9E009E }; -const uint64_t Camellia_SBOX8[256] = {+alignas(64) const uint64_t Camellia_SBOX8[256] = { 0x7070700070707000, 0x8282820082828200, 0x2C2C2C002C2C2C00, 0xECECEC00ECECEC00, 0xB3B3B300B3B3B300, 0x2727270027272700, 0xC0C0C000C0C0C000, 0xE5E5E500E5E5E500, 0xE4E4E400E4E4E400, 0x8585850085858500, 0x5757570057575700, 0x3535350035353500,
third_party/botan/src/lib/block/cast128/cast128.cpp view
@@ -238,7 +238,7 @@ void CAST_128::cast_ks(secure_vector<uint32_t>& K,                        secure_vector<uint32_t>& X)    {-   static const uint32_t S5[256] = {+   alignas(64) static const uint32_t S5[256] = {       0x7EC90C04, 0x2C6E74B9, 0x9B0E66DF, 0xA6337911, 0xB86A7FFF, 0x1DD358F5,       0x44DD9D44, 0x1731167F, 0x08FBF1FA, 0xE7F511CC, 0xD2051B00, 0x735ABA00,       0x2AB722D8, 0x386381CB, 0xACF6243A, 0x69BEFD7A, 0xE6A2E77F, 0xF0C720CD,@@ -283,7 +283,7 @@       0x34010718, 0xBB30CAB8, 0xE822FE15, 0x88570983, 0x750E6249, 0xDA627E55,       0x5E76FFA8, 0xB1534546, 0x6D47DE08, 0xEFE9E7D4 }; -   static const uint32_t S6[256] = {+   alignas(64) static const uint32_t S6[256] = {       0xF6FA8F9D, 0x2CAC6CE1, 0x4CA34867, 0xE2337F7C, 0x95DB08E7, 0x016843B4,       0xECED5CBC, 0x325553AC, 0xBF9F0960, 0xDFA1E2ED, 0x83F0579D, 0x63ED86B9,       0x1AB6A6B8, 0xDE5EBE39, 0xF38FF732, 0x8989B138, 0x33F14961, 0xC01937BD,@@ -328,7 +328,7 @@       0xB0E93524, 0xBEBB8FBD, 0xA2D762CF, 0x49C92F54, 0x38B5F331, 0x7128A454,       0x48392905, 0xA65B1DB8, 0x851C97BD, 0xD675CF2F }; -   static const uint32_t S7[256] = {+   alignas(64) static const uint32_t S7[256] = {       0x85E04019, 0x332BF567, 0x662DBFFF, 0xCFC65693, 0x2A8D7F6F, 0xAB9BC912,       0xDE6008A1, 0x2028DA1F, 0x0227BCE7, 0x4D642916, 0x18FAC300, 0x50F18B82,       0x2CB2CB11, 0xB232E75C, 0x4B3695F2, 0xB28707DE, 0xA05FBCF6, 0xCD4181E9,@@ -373,7 +373,7 @@       0xC3C0BDAE, 0x4958C24C, 0x518F36B2, 0x84B1D370, 0x0FEDCE83, 0x878DDADA,       0xF2A279C7, 0x94E01BE8, 0x90716F4B, 0x954B8AA3 }; -   static const uint32_t S8[256] = {+   alignas(64) static const uint32_t S8[256] = {       0xE216300D, 0xBBDDFFFC, 0xA7EBDABD, 0x35648095, 0x7789F8B7, 0xE6C1121B,       0x0E241600, 0x052CE8B5, 0x11A9CFB0, 0xE5952F11, 0xECE7990A, 0x9386D174,       0x2A42931C, 0x76E38111, 0xB12DEF3A, 0x37DDDDFC, 0xDE9ADEB1, 0x0A0CC32C,
third_party/botan/src/lib/block/cast128/cast_sboxes.h view
@@ -12,7 +12,7 @@  namespace Botan { -const uint32_t CAST_SBOX1[256] = {+alignas(64) const uint32_t CAST_SBOX1[256] = {    0x30FB40D4, 0x9FA0FF0B, 0x6BECCD2F, 0x3F258C7A, 0x1E213F2F, 0x9C004DD3,    0x6003E540, 0xCF9FC949, 0xBFD4AF27, 0x88BBBDB5, 0xE2034090, 0x98D09675,    0x6E63A0E0, 0x15C361D2, 0xC2E7661D, 0x22D4FF8E, 0x28683B6F, 0xC07FD059,@@ -57,7 +57,7 @@    0xB141AB08, 0x7CCA89B9, 0x1A69E783, 0x02CC4843, 0xA2F7C579, 0x429EF47D,    0x427B169C, 0x5AC9F049, 0xDD8F0F00, 0x5C8165BF }; -const uint32_t CAST_SBOX2[256] = {+alignas(64) const uint32_t CAST_SBOX2[256] = {    0x1F201094, 0xEF0BA75B, 0x69E3CF7E, 0x393F4380, 0xFE61CF7A, 0xEEC5207A,    0x55889C94, 0x72FC0651, 0xADA7EF79, 0x4E1D7235, 0xD55A63CE, 0xDE0436BA,    0x99C430EF, 0x5F0C0794, 0x18DCDB7D, 0xA1D6EFF3, 0xA0B52F7B, 0x59E83605,@@ -102,7 +102,7 @@    0x5C038323, 0x3E5D3BB9, 0x43D79572, 0x7E6DD07C, 0x06DFDF1E, 0x6C6CC4EF,    0x7160A539, 0x73BFBE70, 0x83877605, 0x4523ECF1 }; -const uint32_t CAST_SBOX3[256] = {+alignas(64) const uint32_t CAST_SBOX3[256] = {    0x8DEFC240, 0x25FA5D9F, 0xEB903DBF, 0xE810C907, 0x47607FFF, 0x369FE44B,    0x8C1FC644, 0xAECECA90, 0xBEB1F9BF, 0xEEFBCAEA, 0xE8CF1950, 0x51DF07AE,    0x920E8806, 0xF0AD0548, 0xE13C8D83, 0x927010D5, 0x11107D9F, 0x07647DB9,@@ -147,7 +147,7 @@    0x52BCE688, 0x1B03588A, 0xF7BAEFD5, 0x4142ED9C, 0xA4315C11, 0x83323EC5,    0xDFEF4636, 0xA133C501, 0xE9D3531C, 0xEE353783 }; -const uint32_t CAST_SBOX4[256] = {+alignas(64) const uint32_t CAST_SBOX4[256] = {    0x9DB30420, 0x1FB6E9DE, 0xA7BE7BEF, 0xD273A298, 0x4A4F7BDB, 0x64AD8C57,    0x85510443, 0xFA020ED1, 0x7E287AFF, 0xE60FB663, 0x095F35A1, 0x79EBF120,    0xFD059D43, 0x6497B7B1, 0xF3641F63, 0x241E4ADF, 0x28147F5F, 0x4FA2B8CD,
third_party/botan/src/lib/block/des/des_tab.cpp view
@@ -9,7 +9,7 @@  namespace Botan { -const uint32_t DES_SPBOX1[256] = {+alignas(64) const uint32_t DES_SPBOX1[256] = {    0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,    0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,    0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,@@ -54,7 +54,7 @@    0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,    0x00010004, 0x00010400, 0x00000000, 0x01010004 }; -const uint32_t DES_SPBOX2[256] = {+alignas(64) const uint32_t DES_SPBOX2[256] = {    0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,    0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,    0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,@@ -99,7 +99,7 @@    0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,    0x80000000, 0x80100020, 0x80108020, 0x00108000 }; -const uint32_t DES_SPBOX3[256] = {+alignas(64) const uint32_t DES_SPBOX3[256] = {    0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,    0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,    0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,@@ -144,7 +144,7 @@    0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,    0x00020208, 0x00000008, 0x08020008, 0x00020200 }; -const uint32_t DES_SPBOX4[256] = {+alignas(64) const uint32_t DES_SPBOX4[256] = {    0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,    0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,    0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,@@ -189,7 +189,7 @@    0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,    0x00000080, 0x00800000, 0x00002000, 0x00802080 }; -const uint32_t DES_SPBOX5[256] = {+alignas(64) const uint32_t DES_SPBOX5[256] = {    0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,    0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,    0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,@@ -234,7 +234,7 @@    0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,    0x00000000, 0x40080000, 0x02080100, 0x40000100 }; -const uint32_t DES_SPBOX6[256] = {+alignas(64) const uint32_t DES_SPBOX6[256] = {    0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,    0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,    0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,@@ -279,7 +279,7 @@    0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,    0x20404000, 0x20000000, 0x00400010, 0x20004010 }; -const uint32_t DES_SPBOX7[256] = {+alignas(64) const uint32_t DES_SPBOX7[256] = {    0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,    0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,    0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,@@ -324,7 +324,7 @@    0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,    0x04000002, 0x04000800, 0x00000800, 0x00200002 }; -const uint32_t DES_SPBOX8[256] = {+alignas(64) const uint32_t DES_SPBOX8[256] = {    0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,    0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,    0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
third_party/botan/src/lib/block/kasumi/kasumi.cpp view
@@ -16,7 +16,7 @@ /* * KASUMI S-Boxes */-const uint8_t KASUMI_SBOX_S7[128] = {+alignas(64) const uint8_t KASUMI_SBOX_S7[128] = {    0x36, 0x32, 0x3E, 0x38, 0x16, 0x22, 0x5E, 0x60, 0x26, 0x06, 0x3F, 0x5D,    0x02, 0x12, 0x7B, 0x21, 0x37, 0x71, 0x27, 0x72, 0x15, 0x43, 0x41, 0x0C,    0x2F, 0x49, 0x2E, 0x1B, 0x19, 0x6F, 0x7C, 0x51, 0x35, 0x09, 0x79, 0x4F,@@ -29,7 +29,7 @@    0x44, 0x1D, 0x73, 0x2C, 0x40, 0x6B, 0x6C, 0x18, 0x6E, 0x53, 0x24, 0x4E,    0x2A, 0x13, 0x0F, 0x29, 0x58, 0x77, 0x3B, 0x03 }; -const uint16_t KASUMI_SBOX_S9[512] = {+alignas(64) const uint16_t KASUMI_SBOX_S9[512] = {    0x00A7, 0x00EF, 0x00A1, 0x017B, 0x0187, 0x014E, 0x0009, 0x0152, 0x0026,    0x00E2, 0x0030, 0x0166, 0x01C4, 0x0181, 0x005A, 0x018D, 0x00B7, 0x00FD,    0x0093, 0x014B, 0x019F, 0x0154, 0x0033, 0x016A, 0x0132, 0x01F4, 0x0106,
third_party/botan/src/lib/block/misty1/misty1.cpp view
@@ -12,7 +12,7 @@  namespace { -static const uint8_t MISTY1_SBOX_S7[128] = {+alignas(64) static const uint8_t MISTY1_SBOX_S7[128] = {    0x1B, 0x32, 0x33, 0x5A, 0x3B, 0x10, 0x17, 0x54, 0x5B, 0x1A, 0x72, 0x73,    0x6B, 0x2C, 0x66, 0x49, 0x1F, 0x24, 0x13, 0x6C, 0x37, 0x2E, 0x3F, 0x4A,    0x5D, 0x0F, 0x40, 0x56, 0x25, 0x51, 0x1C, 0x04, 0x0B, 0x46, 0x20, 0x0D,@@ -25,7 +25,7 @@    0x2D, 0x7A, 0x7F, 0x61, 0x50, 0x22, 0x11, 0x06, 0x47, 0x16, 0x52, 0x4E,    0x71, 0x3E, 0x69, 0x43, 0x34, 0x5C, 0x58, 0x7D }; -static const uint16_t MISTY1_SBOX_S9[512] = {+alignas(64) static const uint16_t MISTY1_SBOX_S9[512] = {    0x01C3, 0x00CB, 0x0153, 0x019F, 0x01E3, 0x00E9, 0x00FB, 0x0035, 0x0181,    0x00B9, 0x0117, 0x01EB, 0x0133, 0x0009, 0x002D, 0x00D3, 0x00C7, 0x014A,    0x0037, 0x007E, 0x00EB, 0x0164, 0x0193, 0x01D8, 0x00A3, 0x011E, 0x0055,
third_party/botan/src/lib/block/seed/seed.cpp view
@@ -12,7 +12,7 @@  namespace { -const uint32_t SEED_S0[256] = {+alignas(64) const uint32_t SEED_S0[256] = {    0x2989A1A8, 0x05858184, 0x16C6D2D4, 0x13C3D3D0, 0x14445054, 0x1D0D111C,    0x2C8CA0AC, 0x25052124, 0x1D4D515C, 0x03434340, 0x18081018, 0x1E0E121C,    0x11415150, 0x3CCCF0FC, 0x0ACAC2C8, 0x23436360, 0x28082028, 0x04444044,@@ -57,7 +57,7 @@    0x07070304, 0x33033330, 0x28C8E0E8, 0x1B0B1318, 0x05050104, 0x39497178,    0x10809090, 0x2A4A6268, 0x2A0A2228, 0x1A8A9298 }; -const uint32_t SEED_S1[256] = {+alignas(64) const uint32_t SEED_S1[256] = {    0x38380830, 0xE828C8E0, 0x2C2D0D21, 0xA42686A2, 0xCC0FCFC3, 0xDC1ECED2,    0xB03383B3, 0xB83888B0, 0xAC2F8FA3, 0x60204060, 0x54154551, 0xC407C7C3,    0x44044440, 0x6C2F4F63, 0x682B4B63, 0x581B4B53, 0xC003C3C3, 0x60224262,@@ -102,7 +102,7 @@    0x080A0A02, 0x84078783, 0xD819C9D1, 0x4C0C4C40, 0x80038383, 0x8C0F8F83,    0xCC0ECEC2, 0x383B0B33, 0x480A4A42, 0xB43787B3 }; -const uint32_t SEED_S2[256] = {+alignas(64) const uint32_t SEED_S2[256] = {    0xA1A82989, 0x81840585, 0xD2D416C6, 0xD3D013C3, 0x50541444, 0x111C1D0D,    0xA0AC2C8C, 0x21242505, 0x515C1D4D, 0x43400343, 0x10181808, 0x121C1E0E,    0x51501141, 0xF0FC3CCC, 0xC2C80ACA, 0x63602343, 0x20282808, 0x40440444,@@ -147,7 +147,7 @@    0x03040707, 0x33303303, 0xE0E828C8, 0x13181B0B, 0x01040505, 0x71783949,    0x90901080, 0x62682A4A, 0x22282A0A, 0x92981A8A }; -const uint32_t SEED_S3[256] = {+alignas(64) const uint32_t SEED_S3[256] = {    0x08303838, 0xC8E0E828, 0x0D212C2D, 0x86A2A426, 0xCFC3CC0F, 0xCED2DC1E,    0x83B3B033, 0x88B0B838, 0x8FA3AC2F, 0x40606020, 0x45515415, 0xC7C3C407,    0x44404404, 0x4F636C2F, 0x4B63682B, 0x4B53581B, 0xC3C3C003, 0x42626022,
third_party/botan/src/lib/block/twofish/twofish_tab.cpp view
@@ -9,7 +9,7 @@  namespace Botan { -const uint8_t Twofish::Q0[256] = {+alignas(64) const uint8_t Twofish::Q0[256] = {    0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,    0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,    0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,@@ -33,7 +33,7 @@    0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,    0x4A, 0x5E, 0xC1, 0xE0 }; -const uint8_t Twofish::Q1[256] = {+alignas(64) const uint8_t Twofish::Q1[256] = {    0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,    0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,    0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,@@ -57,12 +57,12 @@    0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,    0x55, 0x09, 0xBE, 0x91 }; -const uint8_t Twofish::RS[32] = {+alignas(64) const uint8_t Twofish::RS[32] = {    0x01, 0xA4, 0x02, 0xA4, 0xA4, 0x56, 0xA1, 0x55, 0x55, 0x82, 0xFC, 0x87,    0x87, 0xF3, 0xC1, 0x5A, 0x5A, 0x1E, 0x47, 0x58, 0x58, 0xC6, 0xAE, 0xDB,    0xDB, 0x68, 0x3D, 0x9E, 0x9E, 0xE5, 0x19, 0x03 }; -const uint8_t Twofish::EXP_TO_POLY[255] = {+alignas(64) const uint8_t Twofish::EXP_TO_POLY[255] = {    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,    0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,    0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,@@ -86,7 +86,7 @@    0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,    0x8F, 0x53, 0xA6 }; -const uint8_t Twofish::POLY_TO_EXP[255] = {+alignas(64) const uint8_t Twofish::POLY_TO_EXP[255] = {    0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,    0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,    0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,@@ -110,7 +110,7 @@    0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,    0x85, 0xC8, 0xA1 }; -const uint32_t Twofish::MDS0[256] = {+alignas(64) const uint32_t Twofish::MDS0[256] = {    0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,    0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,    0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,@@ -155,7 +155,7 @@    0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,    0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91 }; -const uint32_t Twofish::MDS1[256] = {+alignas(64) const uint32_t Twofish::MDS1[256] = {    0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,    0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,    0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,@@ -200,7 +200,7 @@    0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,    0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8 }; -const uint32_t Twofish::MDS2[256] = {+alignas(64) const uint32_t Twofish::MDS2[256] = {    0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,    0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,    0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,@@ -245,7 +245,7 @@    0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,    0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF }; -const uint32_t Twofish::MDS3[256] = {+alignas(64) const uint32_t Twofish::MDS3[256] = {    0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,    0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,    0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
third_party/botan/src/lib/codec/base32/base32.cpp view
@@ -1,7 +1,7 @@ /* * Base32 Encoding and Decoding * (C) 2018 Erwan Chaussy-* (C) 2018 Jack Lloyd+* (C) 2018,2020 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */@@ -9,6 +9,7 @@ #include <botan/base32.h> #include <botan/internal/codec_base.h> #include <botan/internal/rounding.h>+#include <botan/internal/ct_utils.h>  namespace Botan { @@ -58,45 +59,11 @@          return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / m_encoding_bytes_out;          } -      static void encode(char out[8], const uint8_t in[5]) noexcept-         {-         out[0] = Base32::m_bin_to_base32[(in[0] & 0xF8) >> 3];-         out[1] = Base32::m_bin_to_base32[((in[0] & 0x07) << 2) | (in[1] >> 6)];-         out[2] = Base32::m_bin_to_base32[((in[1] & 0x3E) >> 1)];-         out[3] = Base32::m_bin_to_base32[((in[1] & 0x01) << 4) | (in[2] >> 4)];-         out[4] = Base32::m_bin_to_base32[((in[2] & 0x0F) << 1) | (in[3] >> 7)];-         out[5] = Base32::m_bin_to_base32[((in[3] & 0x7C) >> 2)];-         out[6] = Base32::m_bin_to_base32[((in[3] & 0x03) << 3) | (in[4] >> 5)];-         out[7] = Base32::m_bin_to_base32[in[4] & 0x1F];-         }--      static inline uint8_t lookup_binary_value(char input) noexcept-         {-         return Base32::m_base32_to_bin[static_cast<uint8_t>(input)];-         }+      static void encode(char out[8], const uint8_t in[5]) noexcept; -      static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws)-         {-         if(bin <= 0x1F)-            {-            return true;-            }-         else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))-            {-            std::string bad_char(1, input);-            if(bad_char == "\t")-               { bad_char = "\\t"; }-            else if(bad_char == "\n")-               { bad_char = "\\n"; }-            else if(bad_char == "\r")-               { bad_char = "\\r"; }+      static uint8_t lookup_binary_value(char input) noexcept; -            throw Invalid_Argument(-               std::string("base32_decode: invalid base32 character '") +-               bad_char + "'");-            }-         return false;-         }+      static bool check_bad_char(uint8_t bin, char input, bool ignore_ws);        static void decode(uint8_t* out_ptr, const uint8_t decode_buf[8])          {@@ -116,55 +83,97 @@       static const size_t m_encoding_bits = 5;       static const size_t m_remaining_bits_before_padding = 6; -       static const size_t m_encoding_bytes_in = 5;       static const size_t m_encoding_bytes_out = 8;+   }; +namespace { -      static const uint8_t m_bin_to_base32[32];-      static const uint8_t m_base32_to_bin[256];-   };+char lookup_base32_char(uint8_t x)+   {+   BOTAN_DEBUG_ASSERT(x < 32); -const uint8_t Base32::m_bin_to_base32[32] =+   const auto in_AZ = CT::Mask<uint8_t>::is_lt(x, 26);++   const char c_AZ = 'A' + x;+   const char c_27 = '2' + (x - 26);++   return in_AZ.select(c_AZ, c_27);+   }++}++//static+void Base32::encode(char out[8], const uint8_t in[5]) noexcept    {-   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',-   'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',-   '2', '3', '4', '5', '6', '7'-   };+   const uint8_t b0 = (in[0] & 0xF8) >> 3;+   const uint8_t b1 = ((in[0] & 0x07) << 2) | (in[1] >> 6);+   const uint8_t b2 = ((in[1] & 0x3E) >> 1);+   const uint8_t b3 = ((in[1] & 0x01) << 4) | (in[2] >> 4);+   const uint8_t b4 = ((in[2] & 0x0F) << 1) | (in[3] >> 7);+   const uint8_t b5 = ((in[3] & 0x7C) >> 2);+   const uint8_t b6 = ((in[3] & 0x03) << 3) | (in[4] >> 5);+   const uint8_t b7 = in[4] & 0x1F; -/*-* base32 Decoder Lookup Table-* Warning: assumes ASCII encodings-*/-const uint8_t Base32::m_base32_to_bin[256] =+   out[0] = lookup_base32_char(b0);+   out[1] = lookup_base32_char(b1);+   out[2] = lookup_base32_char(b2);+   out[3] = lookup_base32_char(b3);+   out[4] = lookup_base32_char(b4);+   out[5] = lookup_base32_char(b5);+   out[6] = lookup_base32_char(b6);+   out[7] = lookup_base32_char(b7);+   }++//static+uint8_t Base32::lookup_binary_value(char input) noexcept    {-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,-   0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04,-   0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,-   0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,-   0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF-   };+   const uint8_t c = static_cast<uint8_t>(input);++   const auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, uint8_t('A'), uint8_t('Z'));+   const auto is_decimal     = CT::Mask<uint8_t>::is_within_range(c, uint8_t('2'), uint8_t('7'));++   const auto is_equal       = CT::Mask<uint8_t>::is_equal(c, uint8_t('='));+   const auto is_whitespace  = CT::Mask<uint8_t>::is_any_of(c, {+         uint8_t(' '), uint8_t('\t'), uint8_t('\n'), uint8_t('\r')+      });++   const uint8_t c_upper = c - uint8_t('A');+   const uint8_t c_decim = c - uint8_t('2') + 26;++   uint8_t ret = 0xFF; // default value++   ret = is_alpha_upper.select(c_upper, ret);+   ret = is_decimal.select(c_decim, ret);+   ret = is_equal.select(0x81, ret);+   ret = is_whitespace.select(0x80, ret);++   return ret;+   }++//static+bool Base32::check_bad_char(uint8_t bin, char input, bool ignore_ws)+   {+   if(bin <= 0x1F)+      {+      return true;+      }+   else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))+      {+      std::string bad_char(1, input);+      if(bad_char == "\t")+         { bad_char = "\\t"; }+      else if(bad_char == "\n")+         { bad_char = "\\n"; }+      else if(bad_char == "\r")+         { bad_char = "\\r"; }++      throw Invalid_Argument(+         std::string("base32_decode: invalid base32 character '") ++         bad_char + "'");+      }+   return false;+   }  } 
third_party/botan/src/lib/codec/base58/base58.cpp view
@@ -1,5 +1,5 @@ /*-* (C) 2018 Jack Lloyd+* (C) 2018,2020 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */@@ -9,6 +9,7 @@ #include <botan/bigint.h> #include <botan/divide.h> #include <botan/loadstor.h>+#include <botan/internal/ct_utils.h> #include <botan/hash.h>  namespace Botan {@@ -30,73 +31,52 @@    return load_be<uint32_t>(checksum.data(), 0);    } -class Character_Table+char lookup_base58_char(uint8_t x)    {-   public:-      // This must be a literal constant-      Character_Table(const char* alphabet) :-         m_alphabet(alphabet)-         {-         const size_t alpha_len = std::strlen(alphabet);--         // 128 or up would flow into 0x80 invalid bit-         if(alpha_len == 0 || alpha_len >= 128)-            throw Invalid_Argument("Bad Character_Table string");--         m_alphabet_len = static_cast<uint8_t>(alpha_len);--         set_mem(m_tab, 256, 0x80);--         for(size_t i = 0; m_alphabet[i]; ++i)-            {-            const uint8_t b = static_cast<uint8_t>(m_alphabet[i]);-            BOTAN_ASSERT(m_tab[b] == 0x80, "No duplicate chars");-            m_tab[b] = static_cast<uint8_t>(i);-            }-         }--      uint8_t radix() const { return m_alphabet_len; }+   // "123456789 ABCDEFGH JKLMN PQRSTUVWXYZ abcdefghijk mnopqrstuvwxyz"+   BOTAN_DEBUG_ASSERT(x < 58); -      char operator[](size_t i) const-         {-         BOTAN_ASSERT(i < m_alphabet_len, "Character in range");-         return m_alphabet[i];-         }+   const auto is_dec_19      = CT::Mask<uint8_t>::is_lte(x, 8);+   const auto is_alpha_AH    = CT::Mask<uint8_t>::is_within_range(x, 9, 16);+   const auto is_alpha_JN    = CT::Mask<uint8_t>::is_within_range(x, 17, 21);+   const auto is_alpha_PZ    = CT::Mask<uint8_t>::is_within_range(x, 22, 32);+   const auto is_alpha_ak    = CT::Mask<uint8_t>::is_within_range(x, 33, 43);+   // otherwise in 'm'-'z' -      uint8_t code_for(char c) const-         {-         return m_tab[static_cast<uint8_t>(c)];-         }+   const char c_19 = '1' + x;+   const char c_AH = 'A' + (x - 9);+   const char c_JN = 'J' + (x - 17);+   const char c_PZ = 'P' + (x - 22);+   const char c_ak = 'a' + (x - 33);+   const char c_mz = 'm' + (x - 44); -   private:-      const char* m_alphabet;-      uint8_t m_alphabet_len;-      uint8_t m_tab[256];-   };+   char ret = c_mz;+   ret = is_dec_19.select(c_19, ret);+   ret = is_alpha_AH.select(c_AH, ret);+   ret = is_alpha_JN.select(c_JN, ret);+   ret = is_alpha_PZ.select(c_PZ, ret);+   ret = is_alpha_ak.select(c_ak, ret); -static const Character_Table& BASE58_ALPHA()-   {-   static const Character_Table base58_alpha("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");-   return base58_alpha;+   return ret;    }  std::string base58_encode(BigInt v, size_t leading_zeros)    {-   const auto base58 = BASE58_ALPHA();+   const uint8_t radix = 58;     std::string result;    BigInt q;-   uint8_t r;     while(v.is_nonzero())       {-      ct_divide_u8(v, base58.radix(), q, r);-      result.push_back(base58[r]);+      uint8_t r;+      ct_divide_u8(v, radix, q, r);+      result.push_back(lookup_base58_char(r));       v.swap(q);       }     for(size_t i = 0; i != leading_zeros; ++i)-      result.push_back(base58[0]);+      result.push_back('1'); // 'zero' byte     return std::string(result.rbegin(), result.rend());    }@@ -112,6 +92,39 @@    return leading_zeros;    } +uint8_t base58_value_of(char input)+   {+   // "123456789 ABCDEFGH JKLMN PQRSTUVWXYZ abcdefghijk mnopqrstuvwxyz"++   const uint8_t c = static_cast<uint8_t>(input);++   const auto is_dec_19      = CT::Mask<uint8_t>::is_within_range(c, uint8_t('1'), uint8_t('9'));+   const auto is_alpha_AH    = CT::Mask<uint8_t>::is_within_range(c, uint8_t('A'), uint8_t('H'));+   const auto is_alpha_JN    = CT::Mask<uint8_t>::is_within_range(c, uint8_t('J'), uint8_t('N'));+   const auto is_alpha_PZ    = CT::Mask<uint8_t>::is_within_range(c, uint8_t('P'), uint8_t('Z'));++   const auto is_alpha_ak    = CT::Mask<uint8_t>::is_within_range(c, uint8_t('a'), uint8_t('k'));+   const auto is_alpha_mz    = CT::Mask<uint8_t>::is_within_range(c, uint8_t('m'), uint8_t('z'));++   const uint8_t c_dec_19 = c - uint8_t('1');+   const uint8_t c_AH     = c - uint8_t('A') + 9;+   const uint8_t c_JN     = c - uint8_t('J') + 17;+   const uint8_t c_PZ     = c - uint8_t('P') + 22;++   const uint8_t c_ak     = c - uint8_t('a') + 33;+   const uint8_t c_mz     = c - uint8_t('m') + 44;++   uint8_t ret = 0xFF; // default value++   ret = is_dec_19.select(c_dec_19, ret);+   ret = is_alpha_AH.select(c_AH, ret);+   ret = is_alpha_JN.select(c_JN, ret);+   ret = is_alpha_PZ.select(c_PZ, ret);+   ret = is_alpha_ak.select(c_ak, ret);+   ret = is_alpha_mz.select(c_mz, ret);+   return ret;+   }+ }  std::string base58_encode(const uint8_t input[], size_t input_length)@@ -130,9 +143,7 @@  std::vector<uint8_t> base58_decode(const char input[], size_t input_length)    {-   const auto base58 = BASE58_ALPHA();--   const size_t leading_zeros = count_leading_zeros(input, input_length, base58[0]);+   const size_t leading_zeros = count_leading_zeros(input, input_length, '1');     BigInt v; @@ -143,12 +154,12 @@       if(c == ' ' || c == '\n')          continue; -      const size_t idx = base58.code_for(c);+      const uint8_t idx = base58_value_of(c); -      if(idx == 0x80)+      if(idx == 0xFF)          throw Decoding_Error("Invalid base58"); -      v *= base58.radix();+      v *= 58;       v += idx;       } 
third_party/botan/src/lib/codec/base64/base64.cpp view
@@ -1,6 +1,6 @@ /* * Base64 Encoding and Decoding-* (C) 2010,2015 Jack Lloyd+* (C) 2010,2015,2020 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */@@ -9,6 +9,7 @@ #include <botan/internal/codec_base.h> #include <botan/exceptn.h> #include <botan/internal/rounding.h>+#include <botan/internal/ct_utils.h>  namespace Botan { @@ -58,41 +59,11 @@          return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / m_encoding_bytes_out;          } -      static void encode(char out[8], const uint8_t in[5]) noexcept-         {-         out[0] = Base64::m_bin_to_base64[(in[0] & 0xFC) >> 2];-         out[1] = Base64::m_bin_to_base64[((in[0] & 0x03) << 4) | (in[1] >> 4)];-         out[2] = Base64::m_bin_to_base64[((in[1] & 0x0F) << 2) | (in[2] >> 6)];-         out[3] = Base64::m_bin_to_base64[in[2] & 0x3F];-         }--      static inline uint8_t lookup_binary_value(char input) noexcept-         {-         return Base64::m_base64_to_bin[static_cast<uint8_t>(input)];-         }+      static void encode(char out[8], const uint8_t in[5]) noexcept; -      static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws)-         {-         if(bin <= 0x3F)-            {-            return true;-            }-         else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))-            {-            std::string bad_char(1, input);-            if(bad_char == "\t")-               { bad_char = "\\t"; }-            else if(bad_char == "\n")-               { bad_char = "\\n"; }-            else if(bad_char == "\r")-               { bad_char = "\\r"; }+      static uint8_t lookup_binary_value(char input) noexcept; -            throw Invalid_Argument(-               std::string("base64_decode: invalid base64 character '") +-               bad_char + "'");-            }-         return false;-         }+      static bool check_bad_char(uint8_t bin, char input, bool ignore_ws);        static void decode(uint8_t* out_ptr, const uint8_t decode_buf[4])          {@@ -110,57 +81,105 @@       static const size_t m_encoding_bits = 6;       static const size_t m_remaining_bits_before_padding = 8; -       static const size_t m_encoding_bytes_in = 3;       static const size_t m_encoding_bytes_out = 4;+   }; +char lookup_base64_char(uint8_t x)+   {+   BOTAN_DEBUG_ASSERT(x < 64); -      static const uint8_t m_bin_to_base64[64];-      static const uint8_t m_base64_to_bin[256];-   };+   const auto in_az = CT::Mask<uint8_t>::is_within_range(x, 26, 51);+   const auto in_09 = CT::Mask<uint8_t>::is_within_range(x, 52, 61);+   const auto eq_plus = CT::Mask<uint8_t>::is_equal(x, 62);+   const auto eq_slash = CT::Mask<uint8_t>::is_equal(x, 63); -const uint8_t Base64::m_bin_to_base64[64] =+   const char c_AZ = 'A' + x;+   const char c_az = 'a' + (x - 26);+   const char c_09 = '0' + (x - 2*26);+   const char c_plus = '+';+   const char c_slash = '/';++   char ret = c_AZ;+   ret = in_az.select(c_az, ret);+   ret = in_09.select(c_09, ret);+   ret = eq_plus.select(c_plus, ret);+   ret = eq_slash.select(c_slash, ret);++   return ret;+   }++//static+void Base64::encode(char out[8], const uint8_t in[5]) noexcept    {-   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',-   'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',-   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',-   'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',-   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'-   };+   const uint8_t b0 = (in[0] & 0xFC) >> 2;+   const uint8_t b1 = ((in[0] & 0x03) << 4) | (in[1] >> 4);+   const uint8_t b2 = ((in[1] & 0x0F) << 2) | (in[2] >> 6);+   const uint8_t b3 = in[2] & 0x3F;+   out[0] = lookup_base64_char(b0);+   out[1] = lookup_base64_char(b1);+   out[2] = lookup_base64_char(b2);+   out[3] = lookup_base64_char(b3);+   } -/*-* base64 Decoder Lookup Table-* Warning: assumes ASCII encodings-*/-const uint8_t Base64::m_base64_to_bin[256] =+//static+uint8_t Base64::lookup_binary_value(char input) noexcept    {-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,-   0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35,-   0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,-   0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04,-   0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,-   0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,-   0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C,-   0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,-   0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,-   0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF-   };+   const uint8_t c = static_cast<uint8_t>(input);++   const auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, uint8_t('A'), uint8_t('Z'));+   const auto is_alpha_lower = CT::Mask<uint8_t>::is_within_range(c, uint8_t('a'), uint8_t('z'));+   const auto is_decimal     = CT::Mask<uint8_t>::is_within_range(c, uint8_t('0'), uint8_t('9'));++   const auto is_plus        = CT::Mask<uint8_t>::is_equal(c, uint8_t('+'));+   const auto is_slash       = CT::Mask<uint8_t>::is_equal(c, uint8_t('/'));+   const auto is_equal       = CT::Mask<uint8_t>::is_equal(c, uint8_t('='));++   const auto is_whitespace  = CT::Mask<uint8_t>::is_any_of(c, {+         uint8_t(' '), uint8_t('\t'), uint8_t('\n'), uint8_t('\r')+      });++   const uint8_t c_upper = c - uint8_t('A');+   const uint8_t c_lower = c - uint8_t('a') + 26;+   const uint8_t c_decim = c - uint8_t('0') + 2*26;++   uint8_t ret = 0xFF; // default value++   ret = is_alpha_upper.select(c_upper, ret);+   ret = is_alpha_lower.select(c_lower, ret);+   ret = is_decimal.select(c_decim, ret);+   ret = is_plus.select(62, ret);+   ret = is_slash.select(63, ret);+   ret = is_equal.select(0x81, ret);+   ret = is_whitespace.select(0x80, ret);++   return ret;+   }++//static+bool Base64::check_bad_char(uint8_t bin, char input, bool ignore_ws)+   {+   if(bin <= 0x3F)+      {+      return true;+      }+   else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))+      {+      std::string bad_char(1, input);+      if(bad_char == "\t")+         { bad_char = "\\t"; }+      else if(bad_char == "\n")+         { bad_char = "\\n"; }+      else if(bad_char == "\r")+         { bad_char = "\\r"; }++      throw Invalid_Argument(+         std::string("base64_decode: invalid base64 character '") ++         bad_char + "'");+      }+   return false;+   }+ }  size_t base64_encode(char out[],
third_party/botan/src/lib/codec/hex/hex.cpp view
@@ -1,6 +1,6 @@ /* * Hex Encoding and Decoding-* (C) 2010 Jack Lloyd+* (C) 2010,2020 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */@@ -8,29 +8,38 @@ #include <botan/hex.h> #include <botan/mem_ops.h> #include <botan/exceptn.h>+#include <botan/internal/ct_utils.h>  namespace Botan { +namespace {++char hex_encode_nibble(uint8_t n, bool uppercase)+   {+   BOTAN_DEBUG_ASSERT(n <= 15);++   const auto in_09 = CT::Mask<uint8_t>::is_lt(n, 10);++   const char c_09 = n + '0';+   const char c_af = n + (uppercase ? 'A' : 'a') - 10;++   return in_09.select(c_09, c_af);+   }++}+ void hex_encode(char output[],                 const uint8_t input[],                 size_t input_length,                 bool uppercase)    {-   static const uint8_t BIN_TO_HEX_UPPER[16] = {-      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',-      'A', 'B', 'C', 'D', 'E', 'F' };--   static const uint8_t BIN_TO_HEX_LOWER[16] = {-      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',-      'a', 'b', 'c', 'd', 'e', 'f' };--   const uint8_t* tbl = uppercase ? BIN_TO_HEX_UPPER : BIN_TO_HEX_LOWER;-    for(size_t i = 0; i != input_length; ++i)       {-      uint8_t x = input[i];-      output[2*i  ] = tbl[(x >> 4) & 0x0F];-      output[2*i+1] = tbl[(x     ) & 0x0F];+      const uint8_t n0 = (input[i] >> 4) & 0xF;+      const uint8_t n1 = (input[i]     ) & 0xF;++      output[2*i  ] = hex_encode_nibble(n0, uppercase);+      output[2*i+1] = hex_encode_nibble(n1, uppercase);       }    } @@ -46,49 +55,43 @@    return output;    } +namespace {++uint8_t hex_char_to_bin(char input)+   {+   const uint8_t c = static_cast<uint8_t>(input);++   const auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, uint8_t('A'), uint8_t('F'));+   const auto is_alpha_lower = CT::Mask<uint8_t>::is_within_range(c, uint8_t('a'), uint8_t('f'));+   const auto is_decimal     = CT::Mask<uint8_t>::is_within_range(c, uint8_t('0'), uint8_t('9'));++   const auto is_whitespace  = CT::Mask<uint8_t>::is_any_of(c, {+         uint8_t(' '), uint8_t('\t'), uint8_t('\n'), uint8_t('\r')+      });++   const uint8_t c_upper = c - uint8_t('A') + 10;+   const uint8_t c_lower = c - uint8_t('a') + 10;+   const uint8_t c_decim = c - uint8_t('0');++   uint8_t ret = 0xFF; // default value++   ret = is_alpha_upper.select(c_upper, ret);+   ret = is_alpha_lower.select(c_lower, ret);+   ret = is_decimal.select(c_decim, ret);+   ret = is_whitespace.select(0x80, ret);++   return ret;+   }++}++ size_t hex_decode(uint8_t output[],                   const char input[],                   size_t input_length,                   size_t& input_consumed,                   bool ignore_ws)    {-   /*-   * Mapping of hex characters to either their binary equivalent-   * or to an error code.-   *  If valid hex (0-9 A-F a-f), the value.-   *  If whitespace, then 0x80-   *  Otherwise 0xFF-   * Warning: this table assumes ASCII character encodings-   */--   static const uint8_t HEX_TO_BIN[256] = {-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,-      0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,-      0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,-      0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,-      0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,-      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };-    uint8_t* out_ptr = output;    bool top_nibble = true; @@ -96,7 +99,7 @@     for(size_t i = 0; i != input_length; ++i)       {-      const uint8_t bin = HEX_TO_BIN[static_cast<uint8_t>(input[i])];+      const uint8_t bin = hex_char_to_bin(input[i]);        if(bin >= 0x10)          {
third_party/botan/src/lib/ffi/ffi.cpp view
@@ -200,6 +200,10 @@  int botan_ffi_supports_api(uint32_t api_version)    {+   // This is the API introduced in 2.18+   if(api_version == 20210220)+      return BOTAN_FFI_SUCCESS;+    // This is the API introduced in 2.13    if(api_version == 20191214)       return BOTAN_FFI_SUCCESS;
third_party/botan/src/lib/ffi/ffi.h view
@@ -1,6 +1,7 @@ /* * FFI (C89 API) * (C) 2015,2017 Jack Lloyd+* (C) 2021 René Fischer * * Botan is released under the Simplified BSD License (see license.txt) */@@ -201,6 +202,20 @@ BOTAN_PUBLIC_API(2,0) int botan_rng_init(botan_rng_t* rng, const char* rng_type);  /**+* Initialize a custom random number generator from a set of callback functions+* @param rng rng object+* @param rng_name name of the rng+* @param context An application-specific context passed to the callback functions+* @param get_cb Callback for getting random bytes from the rng, return 0 for success+* @param add_entry_cb Callback for adding entropy to the rng, return 0 for success, may be NULL+* @param destroy_cb Callback called when rng is destroyed, may be NULL+*/+BOTAN_PUBLIC_API(2,18) int botan_rng_init_custom(botan_rng_t* rng_out, const char* rng_name, void* context,+                                                 int(* get_cb)(void* context, uint8_t* out, size_t out_len),+                                                 int(* add_entropy_cb)(void* context, const uint8_t input[], size_t length),+                                                 void(* destroy_cb)(void* context));++/** * Get random bytes from a random number generator * @param rng rng object * @param out output buffer of size out_len@@ -451,11 +466,6 @@ BOTAN_PUBLIC_API(2,0) int botan_cipher_get_tag_length(botan_cipher_t cipher, size_t* tag_size);  /**-* Get the minimum input size required of the cipher.-*/-BOTAN_PUBLIC_API(2,19) int botan_cipher_get_minimum_final_size(botan_cipher_t cipher, size_t* fs);--/** * Get the default nonce length of this cipher */ BOTAN_PUBLIC_API(2,0) int botan_cipher_get_default_nonce_length(botan_cipher_t cipher, size_t* nl);@@ -1632,29 +1642,6 @@    size_t required_strength,    const char* hostname,    uint64_t reference_time);---typedef struct botan_x509_certstore_struct* botan_x509_certstore_t;--BOTAN_PUBLIC_API(2,19) int botan_x509_certstore_load_file(botan_x509_certstore_t* certstore_obj, const char* certstore_path);--BOTAN_PUBLIC_API(2,19) int botan_x509_certstore_load_system(botan_x509_certstore_t* certstore_obj);--BOTAN_PUBLIC_API(2,19) int botan_x509_certstore_destroy(botan_x509_certstore_t crl);--BOTAN_PUBLIC_API(2,19)-int botan_x509_cert_verify_with_certstore_crl(-   int* result_code,-   botan_x509_cert_t cert,-   const botan_x509_cert_t* intermediates,-   size_t intermediates_len,-   const botan_x509_certstore_t store,-   const botan_x509_crl_t* crls,-   size_t crls_len,-   size_t required_strength,-   const char* hostname_cstr,-   uint64_t reference_time);-  /**  * Key wrapping as per RFC 3394
third_party/botan/src/lib/ffi/ffi_cert.cpp view
@@ -12,20 +12,9 @@    #include <botan/x509cert.h>    #include <botan/x509path.h>    #include <botan/x509_crl.h>-   #include <botan/certstor.h>    #include <botan/data_src.h> #endif -#if defined(BOTAN_HAS_CERTSTOR_FLATFILE)-   #include <botan/certstor_flatfile.h>-#endif--#if defined(BOTAN_HAS_CERTSTOR_MACOS)-   #include <botan/certstor_macos.h>-#elif defined(BOTAN_HAS_CERTSTOR_WINDOWS)-   #include <botan/certstor_windows.h>-#endif- extern "C" {  using namespace Botan_FFI;@@ -512,131 +501,3 @@    }  }--#if defined(BOTAN_HAS_X509_CERTIFICATES)--BOTAN_FFI_DECLARE_STRUCT(botan_x509_certstore_struct, Botan::Certificate_Store, 0x8BD3442A);--#endif--int botan_x509_certstore_load_file(botan_x509_certstore_t* certstore_obj, const char* certstore_path)-   {-   if(!certstore_obj || !certstore_path)-      return BOTAN_FFI_ERROR_NULL_POINTER;--#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_HAS_CERTSTOR_FLATFILE)--   return ffi_guard_thunk(__func__, [=]() -> int {-      std::unique_ptr<Botan::Certificate_Store> c(new Botan::Flatfile_Certificate_Store(certstore_path));-      *certstore_obj = new botan_x509_certstore_struct(c.release());-      return BOTAN_FFI_SUCCESS;-      });--#else-   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;-#endif-   }--int botan_x509_certstore_load_system(botan_x509_certstore_t* certstore_obj)-   {-   if(!certstore_obj)-      return BOTAN_FFI_ERROR_NULL_POINTER;--#if defined(BOTAN_HAS_X509_CERTIFICATES) --   return ffi_guard_thunk(__func__, [=]() -> int {-#if defined(BOTAN_HAS_CERTSTOR_MACOS)-      std::unique_ptr<Botan::Certificate_Store> c(new Botan::Certificate_Store_MacOS);-#elif defined(BOTAN_HAS_CERTSTOR_WINDOWS)-      std::unique_ptr<Botan::Certificate_Store> c(new Botan::Certificate_Store_Windows);-#elif defined(BOTAN_HAS_CERTSTOR_FLATFILE) && defined(BOTAN_SYSTEM_CERT_BUNDLE)-      std::unique_ptr<Botan::Certificate_Store> c(-          new Botan::Flatfile_Certificate_Store(BOTAN_SYSTEM_CERT_BUNDLE, true));-#else-      return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;-#endif-      *certstore_obj = new botan_x509_certstore_struct(c.release());-      return BOTAN_FFI_SUCCESS;-      });--#else-   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;-#endif-   }--int botan_x509_certstore_destroy(botan_x509_certstore_t certstore)-   {-#if defined(BOTAN_HAS_X509_CERTIFICATES)-   return BOTAN_FFI_CHECKED_DELETE(certstore);-#else-   BOTAN_UNUSED(certstore);-   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;-#endif-   }--int botan_x509_cert_verify_with_certstore_crl(-   int* result_code,-   botan_x509_cert_t cert,-   const botan_x509_cert_t* intermediates,-   size_t intermediates_len,-   const botan_x509_certstore_t store,-   const botan_x509_crl_t* crls,-   size_t crls_len,-   size_t required_strength,-   const char* hostname_cstr,-   uint64_t reference_time)-   {-   if(required_strength == 0)-      required_strength = 110;--#if defined(BOTAN_HAS_X509_CERTIFICATES)-   return ffi_guard_thunk(__func__, [=]() -> int {-      const std::string hostname((hostname_cstr == nullptr) ? "" : hostname_cstr);-      const Botan::Usage_Type usage = Botan::Usage_Type::UNSPECIFIED;-      const auto validation_time = reference_time == 0 ?-         std::chrono::system_clock::now() :-         std::chrono::system_clock::from_time_t(static_cast<time_t>(reference_time));--      std::vector<Botan::X509_Certificate> end_certs;-      end_certs.push_back(safe_get(cert));-      for(size_t i = 0; i != intermediates_len; ++i)-         end_certs.push_back(safe_get(intermediates[i]));--      std::vector<Botan::Certificate_Store*> trusted_roots;-      std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_crls;-      trusted_roots.push_back(&safe_get(store));--      if(crls_len > 0)-         {-         trusted_crls.reset(new Botan::Certificate_Store_In_Memory);-         for(size_t i = 0; i != crls_len; ++i)-            {-            trusted_crls->add_crl(safe_get(crls[i]));-            }-         trusted_roots.push_back(trusted_crls.get());-         }--      Botan::Path_Validation_Restrictions restrictions(false, required_strength);--      auto validation_result = Botan::x509_path_validate(end_certs,-                                                         restrictions,-                                                         trusted_roots,-                                                         hostname,-                                                         usage,-                                                         validation_time);--      if(result_code)-         *result_code = static_cast<int>(validation_result.result());--      if(validation_result.successful_validation())-         return 0;-      else-         return 1;-      });-#else-   BOTAN_UNUSED(result_code, cert, intermediates, intermediates_len, trusted);-   BOTAN_UNUSED(store, hostname_cstr, reference_time, crls, crls_len);-   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;-#endif-   }-
third_party/botan/src/lib/ffi/ffi_cipher.cpp view
@@ -224,11 +224,6 @@    return BOTAN_FFI_DO(Botan::Cipher_Mode, cipher, c, { *tl = c.tag_size(); });    } -int botan_cipher_get_minimum_final_size(botan_cipher_t cipher, size_t* fs)-   {-   return BOTAN_FFI_DO(Botan::Cipher_Mode, cipher, c, { *fs = c.minimum_final_size(); });-   }- int botan_cipher_name(botan_cipher_t cipher, char* name, size_t* name_len)    {    return BOTAN_FFI_DO(Botan::Cipher_Mode, cipher, c, {
third_party/botan/src/lib/ffi/ffi_hotp.cpp view
@@ -8,7 +8,7 @@ #include <botan/internal/ffi_util.h>  #if defined(BOTAN_HAS_HOTP)-   #include <botan/hotp.h>+   #include <botan/otp.h> #endif  extern "C" {
third_party/botan/src/lib/ffi/ffi_mp.cpp view
@@ -192,7 +192,7 @@    {    return BOTAN_FFI_DO(Botan::BigInt, quotient, q, {       Botan::BigInt r;-      Botan::divide(safe_get(x), safe_get(y), q, r);+      Botan::vartime_divide(safe_get(x), safe_get(y), q, r);       safe_get(remainder) = r;       });    }
third_party/botan/src/lib/ffi/ffi_rng.cpp view
@@ -1,5 +1,6 @@ /* * (C) 2015,2017 Jack Lloyd+* (C) 2021 René Fischer * * Botan is released under the Simplified BSD License (see license.txt) */@@ -10,6 +11,8 @@ #include <botan/system_rng.h> #include <botan/auto_rng.h> +#include <functional>+ #if defined(BOTAN_HAS_PROCESSOR_RNG)    #include <botan/processor_rng.h> #endif@@ -56,6 +59,101 @@       return BOTAN_FFI_SUCCESS;       });    }++int botan_rng_init_custom(botan_rng_t* rng_out, const char* rng_name, void* context,+                          int(* get_cb)(void* context, uint8_t* out, size_t out_len),+                          int(* add_entropy_cb)(void* context, const uint8_t input[], size_t length),+                          void(* destroy_cb)(void* context))+{+return ffi_guard_thunk(__func__,[=]() -> int {+   if(rng_out == nullptr)+      return BOTAN_FFI_ERROR_NULL_POINTER;++   if(rng_name == nullptr)+      return BOTAN_FFI_ERROR_NULL_POINTER;++   if(get_cb == nullptr)+      return BOTAN_FFI_ERROR_NULL_POINTER;++   class Custom_RNG : public Botan::RandomNumberGenerator+      {+      public:+         Custom_RNG(const std::string& name, void* context,+                    int(* get_cb)(void* context, uint8_t* out, size_t out_len),+                    int(* add_entropy_cb)(void* context, const uint8_t input[], size_t length),+                    void(* destroy_cb)(void* context)) :+            m_name(name)+            {+               m_context = context;+               m_get_cb = get_cb;+               m_add_entropy_cb = add_entropy_cb;+               m_destroy_cb = destroy_cb;+            }++         ~Custom_RNG()+         {+            if(m_destroy_cb)+            {+               m_destroy_cb(m_context);+            }+         }++         void randomize(uint8_t output[], size_t length) override+         {+            int rc = m_get_cb(m_context, output, length);+            if(rc)+            {+               throw Botan::Invalid_State("Failed to get random from C callback, rc=" + std::to_string(rc));+            }+         }++         bool accepts_input() const override+         {+            return m_add_entropy_cb != nullptr;+         }++         void add_entropy(const uint8_t input[], size_t length) override+         {+            if(m_add_entropy_cb == nullptr)+            {+               return;+            }++            int rc = m_add_entropy_cb(m_context, input, length);+            if(rc)+            {+               throw Botan::Invalid_State("Failed to add entropy via C callback, rc=" + std::to_string(rc));+            }+         }++         std::string name() const override+         {+            return m_name;+         }++         void clear() override+         {+         }++         bool is_seeded() const override+         {+            return true;+         }++      private:+         std::string m_name;+         void* m_context;+         std::function<int(void* context, uint8_t* out, size_t out_len)> m_get_cb;+         std::function<int(void* context, const uint8_t input[], size_t length)> m_add_entropy_cb;+         std::function<void(void* context)> m_destroy_cb;+   };++   std::unique_ptr<Botan::RandomNumberGenerator> rng(new Custom_RNG(rng_name, context, get_cb, add_entropy_cb, destroy_cb));++   *rng_out = new botan_rng_struct(rng.release());+   return BOTAN_FFI_SUCCESS;+   });+}  int botan_rng_destroy(botan_rng_t rng)    {
third_party/botan/src/lib/ffi/ffi_totp.cpp view
@@ -8,7 +8,7 @@ #include <botan/internal/ffi_util.h>  #if defined(BOTAN_HAS_TOTP)-   #include <botan/totp.h>+   #include <botan/otp.h> #endif  extern "C" {
third_party/botan/src/lib/ffi/info.txt view
@@ -1,5 +1,5 @@ <defines>-FFI -> 20191214+FFI -> 20210220 </defines>  <header:internal>
third_party/botan/src/lib/hash/checksum/crc24/crc24.cpp view
@@ -14,7 +14,7 @@  namespace { -const uint32_t CRC24_T0[256] = {+alignas(64) const uint32_t CRC24_T0[256] = {    0x00000000, 0x00FB4C86, 0x000DD58A, 0x00F6990C, 0x00E1E693, 0x001AAA15, 0x00EC3319,    0x00177F9F, 0x003981A1, 0x00C2CD27, 0x0034542B, 0x00CF18AD, 0x00D86732, 0x00232BB4,    0x00D5B2B8, 0x002EFE3E, 0x00894EC5, 0x00720243, 0x00849B4F, 0x007FD7C9, 0x0068A856,@@ -53,7 +53,7 @@    0x000CD1F6, 0x00FA48FA, 0x0001047C, 0x002FFA42, 0x00D4B6C4, 0x00222FC8, 0x00D9634E,    0x00CE1CD1, 0x00355057, 0x00C3C95B, 0x003885DD }; -const uint32_t CRC24_T1[256] = {+alignas(64) const uint32_t CRC24_T1[256] = {    0x00000000, 0x00488F66, 0x00901ECD, 0x00D891AB, 0x00DB711C, 0x0093FE7A, 0x004B6FD1,    0x0003E0B7, 0x00B6E338, 0x00FE6C5E, 0x0026FDF5, 0x006E7293, 0x006D9224, 0x00251D42,    0x00FD8CE9, 0x00B5038F, 0x006CC771, 0x00244817, 0x00FCD9BC, 0x00B456DA, 0x00B7B66D,@@ -92,7 +92,7 @@    0x00FA442B, 0x0022D580, 0x006A5AE6, 0x00DF5969, 0x0097D60F, 0x004F47A4, 0x0007C8C2,    0x00042875, 0x004CA713, 0x009436B8, 0x00DCB9DE }; -const uint32_t CRC24_T2[256] = {+alignas(64) const uint32_t CRC24_T2[256] = {    0x00000000, 0x00D70983, 0x00555F80, 0x00825603, 0x0051F286, 0x0086FB05, 0x0004AD06,    0x00D3A485, 0x0059A88B, 0x008EA108, 0x000CF70B, 0x00DBFE88, 0x00085A0D, 0x00DF538E,    0x005D058D, 0x008A0C0E, 0x00491C91, 0x009E1512, 0x001C4311, 0x00CB4A92, 0x0018EE17,@@ -131,7 +131,7 @@    0x002633E5, 0x00A465E6, 0x00736C65, 0x00F9606B, 0x002E69E8, 0x00AC3FEB, 0x007B3668,    0x00A892ED, 0x007F9B6E, 0x00FDCD6D, 0x002AC4EE }; -const uint32_t CRC24_T3[256] = {+alignas(64) const uint32_t CRC24_T3[256] = {    0x00000000, 0x00520936, 0x00A4126C, 0x00F61B5A, 0x004825D8, 0x001A2CEE, 0x00EC37B4,    0x00BE3E82, 0x006B0636, 0x00390F00, 0x00CF145A, 0x009D1D6C, 0x002323EE, 0x00712AD8,    0x00873182, 0x00D538B4, 0x00D60C6C, 0x0084055A, 0x00721E00, 0x00201736, 0x009E29B4,
third_party/botan/src/lib/hash/checksum/crc32/crc32.cpp view
@@ -15,81 +15,85 @@    return std::unique_ptr<HashFunction>(new CRC32(*this));    } +namespace {++const uint32_t CRC32_T0[256] = {+   0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,+   0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,+   0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,+   0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,+   0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,+   0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,+   0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,+   0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,+   0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,+   0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,+   0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,+   0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,+   0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,+   0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,+   0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,+   0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,+   0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,+   0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,+   0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,+   0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,+   0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,+   0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,+   0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,+   0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,+   0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,+   0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,+   0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,+   0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,+   0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,+   0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,+   0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,+   0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,+   0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,+   0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,+   0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,+   0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,+   0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,+   0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,+   0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,+   0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,+   0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,+   0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,+   0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };++}+ /* * Update a CRC32 Checksum */ void CRC32::add_data(const uint8_t input[], size_t length)    {-   const uint32_t TABLE[256] = {-      0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,-      0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,-      0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,-      0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,-      0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,-      0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,-      0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,-      0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,-      0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,-      0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,-      0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,-      0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,-      0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,-      0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,-      0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,-      0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,-      0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,-      0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,-      0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,-      0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,-      0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,-      0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,-      0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,-      0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,-      0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,-      0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,-      0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,-      0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,-      0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,-      0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,-      0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,-      0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,-      0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,-      0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,-      0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,-      0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,-      0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,-      0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,-      0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,-      0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,-      0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,-      0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,-      0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };-    uint32_t tmp = m_crc;    while(length >= 16)       {-      tmp = TABLE[(tmp ^ input[ 0]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[ 1]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[ 2]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[ 3]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[ 4]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[ 5]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[ 6]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[ 7]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[ 8]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[ 9]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[10]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[11]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[12]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[13]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[14]) & 0xFF] ^ (tmp >> 8);-      tmp = TABLE[(tmp ^ input[15]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[ 0]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[ 1]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[ 2]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[ 3]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[ 4]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[ 5]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[ 6]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[ 7]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[ 8]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[ 9]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[10]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[11]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[12]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[13]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[14]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[15]) & 0xFF] ^ (tmp >> 8);       input += 16;       length -= 16;       }     for(size_t i = 0; i != length; ++i)-      tmp = TABLE[(tmp ^ input[i]) & 0xFF] ^ (tmp >> 8);+      tmp = CRC32_T0[(tmp ^ input[i]) & 0xFF] ^ (tmp >> 8);     m_crc = tmp;    }
third_party/botan/src/lib/hash/whirlpool/whrl_tab.cpp view
@@ -9,7 +9,7 @@  namespace Botan { -const uint64_t Whirlpool::C0[256] = {+alignas(64) const uint64_t Whirlpool::C0[256] = { 0x18186018C07830D8, 0x23238C2305AF4626, 0xC6C63FC67EF991B8, 0xE8E887E8136FCDFB, 0x878726874CA113CB, 0xB8B8DAB8A9626D11, 0x0101040108050209, 0x4F4F214F426E9E0D, 0x3636D836ADEE6C9B, 0xA6A6A2A6590451FF, 0xD2D26FD2DEBDB90C, 0xF5F5F3F5FB06F70E,@@ -75,7 +75,7 @@ 0xCCCC17CC2EDB85E2, 0x424215422A578468, 0x98985A98B4C22D2C, 0xA4A4AAA4490E55ED, 0x2828A0285D885075, 0x5C5C6D5CDA31B886, 0xF8F8C7F8933FED6B, 0x8686228644A411C2 }; -const uint64_t Whirlpool::C1[256] = {+alignas(64) const uint64_t Whirlpool::C1[256] = { 0xD818186018C07830, 0x2623238C2305AF46, 0xB8C6C63FC67EF991, 0xFBE8E887E8136FCD, 0xCB878726874CA113, 0x11B8B8DAB8A9626D, 0x0901010401080502, 0x0D4F4F214F426E9E, 0x9B3636D836ADEE6C, 0xFFA6A6A2A6590451, 0x0CD2D26FD2DEBDB9, 0x0EF5F5F3F5FB06F7,@@ -141,7 +141,7 @@ 0xE2CCCC17CC2EDB85, 0x68424215422A5784, 0x2C98985A98B4C22D, 0xEDA4A4AAA4490E55, 0x752828A0285D8850, 0x865C5C6D5CDA31B8, 0x6BF8F8C7F8933FED, 0xC28686228644A411 }; -const uint64_t Whirlpool::C2[256] = {+alignas(64) const uint64_t Whirlpool::C2[256] = { 0x30D818186018C078, 0x462623238C2305AF, 0x91B8C6C63FC67EF9, 0xCDFBE8E887E8136F, 0x13CB878726874CA1, 0x6D11B8B8DAB8A962, 0x0209010104010805, 0x9E0D4F4F214F426E, 0x6C9B3636D836ADEE, 0x51FFA6A6A2A65904, 0xB90CD2D26FD2DEBD, 0xF70EF5F5F3F5FB06,@@ -207,7 +207,7 @@ 0x85E2CCCC17CC2EDB, 0x8468424215422A57, 0x2D2C98985A98B4C2, 0x55EDA4A4AAA4490E, 0x50752828A0285D88, 0xB8865C5C6D5CDA31, 0xED6BF8F8C7F8933F, 0x11C28686228644A4 }; -const uint64_t Whirlpool::C3[256] = {+alignas(64) const uint64_t Whirlpool::C3[256] = { 0x7830D818186018C0, 0xAF462623238C2305, 0xF991B8C6C63FC67E, 0x6FCDFBE8E887E813, 0xA113CB878726874C, 0x626D11B8B8DAB8A9, 0x0502090101040108, 0x6E9E0D4F4F214F42, 0xEE6C9B3636D836AD, 0x0451FFA6A6A2A659, 0xBDB90CD2D26FD2DE, 0x06F70EF5F5F3F5FB,@@ -273,7 +273,7 @@ 0xDB85E2CCCC17CC2E, 0x578468424215422A, 0xC22D2C98985A98B4, 0x0E55EDA4A4AAA449, 0x8850752828A0285D, 0x31B8865C5C6D5CDA, 0x3FED6BF8F8C7F893, 0xA411C28686228644 }; -const uint64_t Whirlpool::C4[256] = {+alignas(64) const uint64_t Whirlpool::C4[256] = { 0xC07830D818186018, 0x05AF462623238C23, 0x7EF991B8C6C63FC6, 0x136FCDFBE8E887E8, 0x4CA113CB87872687, 0xA9626D11B8B8DAB8, 0x0805020901010401, 0x426E9E0D4F4F214F, 0xADEE6C9B3636D836, 0x590451FFA6A6A2A6, 0xDEBDB90CD2D26FD2, 0xFB06F70EF5F5F3F5,@@ -339,7 +339,7 @@ 0x2EDB85E2CCCC17CC, 0x2A57846842421542, 0xB4C22D2C98985A98, 0x490E55EDA4A4AAA4, 0x5D8850752828A028, 0xDA31B8865C5C6D5C, 0x933FED6BF8F8C7F8, 0x44A411C286862286 }; -const uint64_t Whirlpool::C5[256] = {+alignas(64) const uint64_t Whirlpool::C5[256] = { 0x18C07830D8181860, 0x2305AF462623238C, 0xC67EF991B8C6C63F, 0xE8136FCDFBE8E887, 0x874CA113CB878726, 0xB8A9626D11B8B8DA, 0x0108050209010104, 0x4F426E9E0D4F4F21, 0x36ADEE6C9B3636D8, 0xA6590451FFA6A6A2, 0xD2DEBDB90CD2D26F, 0xF5FB06F70EF5F5F3,@@ -405,7 +405,7 @@ 0xCC2EDB85E2CCCC17, 0x422A578468424215, 0x98B4C22D2C98985A, 0xA4490E55EDA4A4AA, 0x285D8850752828A0, 0x5CDA31B8865C5C6D, 0xF8933FED6BF8F8C7, 0x8644A411C2868622 }; -const uint64_t Whirlpool::C6[256] = {+alignas(64) const uint64_t Whirlpool::C6[256] = { 0x6018C07830D81818, 0x8C2305AF46262323, 0x3FC67EF991B8C6C6, 0x87E8136FCDFBE8E8, 0x26874CA113CB8787, 0xDAB8A9626D11B8B8, 0x0401080502090101, 0x214F426E9E0D4F4F, 0xD836ADEE6C9B3636, 0xA2A6590451FFA6A6, 0x6FD2DEBDB90CD2D2, 0xF3F5FB06F70EF5F5,@@ -471,7 +471,7 @@ 0x17CC2EDB85E2CCCC, 0x15422A5784684242, 0x5A98B4C22D2C9898, 0xAAA4490E55EDA4A4, 0xA0285D8850752828, 0x6D5CDA31B8865C5C, 0xC7F8933FED6BF8F8, 0x228644A411C28686 }; -const uint64_t Whirlpool::C7[256] = {+alignas(64) const uint64_t Whirlpool::C7[256] = { 0x186018C07830D818, 0x238C2305AF462623, 0xC63FC67EF991B8C6, 0xE887E8136FCDFBE8, 0x8726874CA113CB87, 0xB8DAB8A9626D11B8, 0x0104010805020901, 0x4F214F426E9E0D4F, 0x36D836ADEE6C9B36, 0xA6A2A6590451FFA6, 0xD26FD2DEBDB90CD2, 0xF5F3F5FB06F70EF5,
third_party/botan/src/lib/kdf/prf_x942/prf_x942.h view
@@ -9,7 +9,7 @@ #define BOTAN_ANSI_X942_PRF_H_  #include <botan/kdf.h>-#include <botan/asn1_oid.h>+#include <botan/asn1_obj.h>  BOTAN_FUTURE_INTERNAL_HEADER(prf_x942.h) 
third_party/botan/src/lib/math/bigint/big_ops3.cpp view
@@ -91,15 +91,41 @@ */ BigInt operator/(const BigInt& x, const BigInt& y)    {-   if(y.sig_words() == 1 && is_power_of_2(y.word_at(0)))-      return (x >> (y.bits() - 1));+   if(y.sig_words() == 1)+      {+      return x / y.word_at(0);+      }     BigInt q, r;-   divide(x, y, q, r);+   vartime_divide(x, y, q, r);    return q;    }  /*+* Division Operator+*/+BigInt operator/(const BigInt& x, word y)+   {+   if(y == 0)+      throw BigInt::DivideByZero();+   else if(y == 1)+      return x;+   else if(y == 2)+      return (x >> 1);+   else if(y <= 255)+      {+      BigInt q;+      uint8_t r;+      ct_divide_u8(x, static_cast<uint8_t>(y), q, r);+      return q;+      }++   BigInt q, r;+   vartime_divide(x, y, q, r);+   return q;+   }++/* * Modulo Operator */ BigInt operator%(const BigInt& n, const BigInt& mod)@@ -111,8 +137,13 @@    if(n.is_positive() && mod.is_positive() && n < mod)       return n; +   if(mod.sig_words() == 1)+      {+      return n % mod.word_at(0);+      }+    BigInt q, r;-   divide(n, mod, q, r);+   vartime_divide(n, mod, q, r);    return r;    } 
third_party/botan/src/lib/math/bigint/bigint.cpp view
@@ -89,14 +89,13 @@  BigInt::BigInt(const uint8_t buf[], size_t length, size_t max_bits)    {-   const size_t max_bytes = std::min(length, (max_bits + 7) / 8);-   binary_decode(buf, max_bytes);+   if(8 * length > max_bits)+      length = (max_bits + 7) / 8; -   const size_t b = this->bits();-   if(b > max_bits)-      {-      *this >>= (b - max_bits);-      }+   binary_decode(buf, length);++   if(8 * length > max_bits)+      *this >>= (8 - (max_bits % 8));    }  /*@@ -166,8 +165,8 @@     if(other.is_negative() && this->is_negative())       {-      return !bigint_ct_is_lt(other.data(), other.sig_words(),-                              this->data(), this->sig_words(), true).is_set();+      return bigint_ct_is_lt(other.data(), other.sig_words(),+                             this->data(), this->sig_words()).is_set();       }     return bigint_ct_is_lt(this->data(), this->sig_words(),
third_party/botan/src/lib/math/bigint/bigint.h view
@@ -1097,6 +1097,7 @@ inline BigInt operator*(word x, const BigInt& y) { return y*x; }  BigInt BOTAN_PUBLIC_API(2,0) operator/(const BigInt& x, const BigInt& d);+BigInt BOTAN_PUBLIC_API(2,0) operator/(const BigInt& x, word m); BigInt BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, const BigInt& m); word   BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, word m); BigInt BOTAN_PUBLIC_API(2,0) operator<<(const BigInt& x, size_t n);
third_party/botan/src/lib/math/bigint/divide.cpp view
@@ -156,7 +156,7 @@ * * See Handbook of Applied Cryptography section 14.2.5 */-void divide(const BigInt& x, const BigInt& y_arg, BigInt& q_out, BigInt& r_out)+void vartime_divide(const BigInt& x, const BigInt& y_arg, BigInt& q_out, BigInt& r_out)    {    if(y_arg.is_zero())       throw BigInt::DivideByZero();
third_party/botan/src/lib/math/bigint/divide.h view
@@ -21,10 +21,10 @@ * @param q will be set to x / y * @param r will be set to x % y */-void BOTAN_PUBLIC_API(2,0) divide(const BigInt& x,-                                  const BigInt& y,-                                  BigInt& q,-                                  BigInt& r);+void BOTAN_UNSTABLE_API vartime_divide(const BigInt& x,+                                       const BigInt& y,+                                       BigInt& q,+                                       BigInt& r);  /** * BigInt division, const time variant@@ -41,6 +41,14 @@                                      const BigInt& y,                                      BigInt& q,                                      BigInt& r);++inline void divide(const BigInt& x,+                   const BigInt& y,+                   BigInt& q,+                   BigInt& r)+   {+   ct_divide(x, y, q, r);+   }  /** * BigInt division, const time variant
third_party/botan/src/lib/math/numbertheory/monty.h view
@@ -8,6 +8,7 @@ #define BOTAN_MONTY_INT_H_  #include <botan/bigint.h>+BOTAN_FUTURE_INTERNAL_HEADER(monty.h)  namespace Botan { 
third_party/botan/src/lib/math/numbertheory/numthry.cpp view
@@ -61,13 +61,29 @@    return seen_nonempty_word.if_set_return(low_zero);    } +namespace {++size_t safegcd_loop_bound(size_t f_bits, size_t g_bits)+   {+   const size_t d = std::max(f_bits, g_bits);++   if(d < 46)+      return (49*d + 80) / 17;+   else+      return (49*d + 57) / 17;+   }++}+ /* * Calculate the GCD */ BigInt gcd(const BigInt& a, const BigInt& b)    {-   if(a.is_zero() || b.is_zero())-      return 0;+   if(a.is_zero())+      return abs(b);+   if(b.is_zero())+      return abs(a);    if(a == 1 || b == 1)       return 1; @@ -91,7 +107,7 @@     int32_t delta = 1; -   const size_t loop_cnt = 4 + 3*std::max(f.bits(), g.bits());+   const size_t loop_cnt = safegcd_loop_bound(f.bits(), g.bits());     BigInt newg, t;    for(size_t i = 0; i != loop_cnt; ++i)@@ -100,8 +116,8 @@        const bool need_swap = (g.is_odd() && delta > 0); -      // if(need_swap) delta *= -1-      delta *= CT::Mask<uint8_t>::expand(need_swap).select(0, 2) - 1;+      // if(need_swap) { delta *= -1 } else { delta *= 1 }+      delta *= CT::Mask<uint8_t>::expand(need_swap).if_not_set_return(2) - 1;       f.ct_cond_swap(need_swap, g);       g.ct_cond_swap(need_swap, newg); @@ -115,6 +131,8 @@     f.const_time_unpoison();    g.const_time_unpoison();++   BOTAN_ASSERT_NOMSG(g.is_zero());     return f;    }
third_party/botan/src/lib/math/numbertheory/numthry.h view
@@ -21,9 +21,10 @@ * @param c an integer * @return (a*b)+c */-BigInt BOTAN_PUBLIC_API(2,0) mul_add(const BigInt& a,-                                     const BigInt& b,-                                     const BigInt& c);+BigInt BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Just use (a*b)+c")+   mul_add(const BigInt& a,+           const BigInt& b,+           const BigInt& c);  /** * Fused subtract-multiply@@ -32,9 +33,10 @@ * @param c an integer * @return (a-b)*c */-BigInt BOTAN_PUBLIC_API(2,0) sub_mul(const BigInt& a,-                                     const BigInt& b,-                                     const BigInt& c);+BigInt BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Just use (a-b)*c")+   sub_mul(const BigInt& a,+           const BigInt& b,+           const BigInt& c);  /** * Fused multiply-subtract@@ -43,9 +45,10 @@ * @param c an integer * @return (a*b)-c */-BigInt BOTAN_PUBLIC_API(2,0) mul_sub(const BigInt& a,-                                     const BigInt& b,-                                     const BigInt& c);+BigInt BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Just use (a*b)-c")+   mul_sub(const BigInt& a,+           const BigInt& b,+           const BigInt& c);  /** * Return the absolute value@@ -102,21 +105,23 @@ /** * Deprecated modular inversion function. Use inverse_mod instead. */-BigInt BOTAN_DEPRECATED_API("Use inverse_mod") ct_inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod);+BigInt BOTAN_DEPRECATED_API("Use inverse_mod") ct_inverse_mod_odd_modulus(const BigInt& x, const BigInt& modulus);  /** * Return a^-1 * 2^k mod b * Returns k, between n and 2n * Not const time */-size_t BOTAN_PUBLIC_API(2,0) almost_montgomery_inverse(BigInt& result,-                                                       const BigInt& a,-                                                       const BigInt& b);+size_t BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use inverse_mod")+   almost_montgomery_inverse(BigInt& result,+                             const BigInt& a,+                             const BigInt& b);  /** * Call almost_montgomery_inverse and correct the result to a^-1 mod b */-BigInt BOTAN_PUBLIC_API(2,0) normalized_montgomery_inverse(const BigInt& a, const BigInt& b);+BigInt BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use inverse_mod")+   normalized_montgomery_inverse(const BigInt& a, const BigInt& b);   /**@@ -143,7 +148,7 @@  /** * Compute the square root of x modulo a prime using the-* Shanks-Tonnelli algorithm+* Tonelli-Shanks algorithm * * @param x the input * @param p the prime@@ -156,13 +161,14 @@ * is even. If input is odd, then input and 2^n are relatively prime * and an inverse exists. */-word BOTAN_PUBLIC_API(2,0) monty_inverse(word input);+word BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use inverse_mod")+   monty_inverse(word input);  /**-* @param x a positive integer-* @return count of the zero bits in x, or, equivalently, the largest-*         value of n such that 2^n divides x evenly. Returns zero if-*         n is less than or equal to zero.+* @param x an integer+* @return count of the low zero bits in x, or, equivalently, the+*         largest value of n such that 2^n divides x evenly. Returns+*         zero if x is equal to zero. */ size_t BOTAN_PUBLIC_API(2,0) low_zero_bits(const BigInt& x); @@ -188,13 +194,16 @@ */ BigInt BOTAN_PUBLIC_API(2,8) is_perfect_square(const BigInt& x); -inline bool quick_check_prime(const BigInt& n, RandomNumberGenerator& rng)+inline bool BOTAN_DEPRECATED("Use is_prime")+   quick_check_prime(const BigInt& n, RandomNumberGenerator& rng)    { return is_prime(n, rng, 32); } -inline bool check_prime(const BigInt& n, RandomNumberGenerator& rng)+inline bool BOTAN_DEPRECATED("Use is_prime")+   check_prime(const BigInt& n, RandomNumberGenerator& rng)    { return is_prime(n, rng, 56); } -inline bool verify_prime(const BigInt& n, RandomNumberGenerator& rng)+inline bool BOTAN_DEPRECATED("Use is_prime")+   verify_prime(const BigInt& n, RandomNumberGenerator& rng)    { return is_prime(n, rng, 80); }  /**@@ -248,7 +257,7 @@ * @param qbits how long q will be in bits * @return random seed used to generate this parameter set */-std::vector<uint8_t> BOTAN_PUBLIC_API(2,0)+std::vector<uint8_t> BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use DL_Group") generate_dsa_primes(RandomNumberGenerator& rng,                     BigInt& p_out, BigInt& q_out,                     size_t pbits, size_t qbits);@@ -265,7 +274,7 @@ * @return true if seed generated a valid DSA parameter set, otherwise           false. p_out and q_out are only valid if true was returned. */-bool BOTAN_PUBLIC_API(2,0)+bool BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use DL_Group") generate_dsa_primes(RandomNumberGenerator& rng,                     BigInt& p_out, BigInt& q_out,                     size_t pbits, size_t qbits,@@ -278,7 +287,7 @@ const size_t PRIME_TABLE_SIZE = 6541;  /**-* A const array of all primes less than 65535+* A const array of all odd primes less than 65535 */ extern const uint16_t BOTAN_PUBLIC_API(2,0) PRIMES[]; 
third_party/botan/src/lib/math/numbertheory/ressol.cpp view
@@ -1,6 +1,5 @@ /*-* Shanks-Tonnelli (RESSOL)-* (C) 2007-2008 Falko Strenzke, FlexSecure GmbH+* (C) 2007,2008 Falko Strenzke, FlexSecure GmbH * (C) 2008 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt)@@ -12,10 +11,13 @@ namespace Botan {  /*-* Shanks-Tonnelli algorithm+* Tonelli-Shanks algorithm */ BigInt ressol(const BigInt& a, const BigInt& p)    {+   if(p <= 1 || p.is_even())+      throw Invalid_Argument("ressol: invalid prime");+    if(a == 0)       return 0;    else if(a < 0)@@ -25,16 +27,14 @@     if(p == 2)       return a;-   else if(p <= 1)-      throw Invalid_Argument("ressol: prime must be > 1 a");-   else if(p.is_even())-      throw Invalid_Argument("ressol: invalid prime");     if(jacobi(a, p) != 1) // not a quadratic residue       return -BigInt(1); -   if(p % 4 == 3)+   if(p % 4 == 3) // The easy case+      {       return power_mod(a, ((p+1) >> 2), p);+      }     size_t s = low_zero_bits(p - 1);    BigInt q = p >> s;@@ -51,10 +51,23 @@    if(n == 1)       return r; -   // find random non quadratic residue z-   BigInt z = 2;-   while(jacobi(z, p) == 1) // while z quadratic residue-      ++z;+   // find random quadratic nonresidue z+   word z = 2;+   for(;;)+      {+      if(jacobi(z, p) == -1) // found one+         break;++      z += 1; // try next z++      /*+      * The expected number of tests to find a non-residue modulo a+      * prime is 2. If we have not found one after 256 then almost+      * certainly we have been given a non-prime p.+      */+      if(z >= 256)+         return -BigInt(1);+      }     BigInt c = power_mod(z, (q << 1) + 1, p); 
third_party/botan/src/lib/misc/hotp/hotp.cpp view
@@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/hotp.h>+#include <botan/otp.h> #include <botan/loadstor.h> #include <botan/exceptn.h> 
third_party/botan/src/lib/misc/hotp/hotp.h view
@@ -8,56 +8,7 @@ #ifndef BOTAN_HOTP_H_ #define BOTAN_HOTP_H_ -#include <botan/mac.h>--namespace Botan {--/**-* HOTP one time passwords (RFC 4226)-*/-class BOTAN_PUBLIC_API(2,2) HOTP final-   {-   public:-      /**-      * @param key the secret key shared between client and server-      * @param hash_algo the hash algorithm to use, should be SHA-1 or SHA-256-      * @param digits the number of digits in the OTP (must be 6, 7, or 8)-      */-      HOTP(const SymmetricKey& key, const std::string& hash_algo = "SHA-1", size_t digits = 6) :-         HOTP(key.begin(), key.size(), hash_algo, digits) {}--      /**-      * @param key the secret key shared between client and server-      * @param key_len length of key param-      * @param hash_algo the hash algorithm to use, should be SHA-1 or SHA-256-      * @param digits the number of digits in the OTP (must be 6, 7, or 8)-      */-      HOTP(const uint8_t key[], size_t key_len,-           const std::string& hash_algo = "SHA-1",-           size_t digits = 6);--      /**-      * Generate the HOTP for a particular counter value-      * @warning if the counter value is repeated the OTP ceases to be one-time-      */-      uint32_t generate_hotp(uint64_t counter);--      /**-      * Check an OTP value using a starting counter and a resync range-      * @param otp the client provided OTP-      * @param starting_counter the server's guess as to the current counter state-      * @param resync_range if 0 then only HOTP(starting_counter) is accepted-      * If larger than 0, up to resync_range values after HOTP are also checked.-      * @return (valid,next_counter). If the OTP does not validate, always-      * returns (false,starting_counter). Otherwise returns (true,next_counter)-      * where next_counter is at most starting_counter + resync_range + 1-      */-      std::pair<bool,uint64_t> verify_hotp(uint32_t otp, uint64_t starting_counter, size_t resync_range = 0);-   private:-      std::unique_ptr<MessageAuthenticationCode> m_mac;-      uint32_t m_digit_mod;-   };--}+#include <botan/otp.h>+BOTAN_DEPRECATED_HEADER(hotp.h)  #endif
+ third_party/botan/src/lib/misc/hotp/otp.h view
@@ -0,0 +1,117 @@+/*+* HOTP/TOTP+* (C) 2017 Jack Lloyd+*+* Botan is released under the Simplified BSD License (see license.txt)+*/++#ifndef BOTAN_ONE_TIME_PASSWORDS_H_+#define BOTAN_ONE_TIME_PASSWORDS_H_++#include <botan/mac.h>+#include <chrono>++namespace Botan {++/**+* HOTP one time passwords (RFC 4226)+*/+class BOTAN_PUBLIC_API(2,2) HOTP final+   {+   public:+      /**+      * @param key the secret key shared between client and server+      * @param hash_algo the hash algorithm to use, should be SHA-1 or SHA-256+      * @param digits the number of digits in the OTP (must be 6, 7, or 8)+      */+      HOTP(const SymmetricKey& key, const std::string& hash_algo = "SHA-1", size_t digits = 6) :+         HOTP(key.begin(), key.size(), hash_algo, digits) {}++      /**+      * @param key the secret key shared between client and server+      * @param key_len length of key param+      * @param hash_algo the hash algorithm to use, should be SHA-1 or SHA-256+      * @param digits the number of digits in the OTP (must be 6, 7, or 8)+      */+      HOTP(const uint8_t key[], size_t key_len,+           const std::string& hash_algo = "SHA-1",+           size_t digits = 6);++      /**+      * Generate the HOTP for a particular counter value+      * @warning if the counter value is repeated the OTP ceases to be one-time+      */+      uint32_t generate_hotp(uint64_t counter);++      /**+      * Check an OTP value using a starting counter and a resync range+      * @param otp the client provided OTP+      * @param starting_counter the server's guess as to the current counter state+      * @param resync_range if 0 then only HOTP(starting_counter) is accepted+      * If larger than 0, up to resync_range values after HOTP are also checked.+      * @return (valid,next_counter). If the OTP does not validate, always+      * returns (false,starting_counter). Otherwise returns (true,next_counter)+      * where next_counter is at most starting_counter + resync_range + 1+      */+      std::pair<bool,uint64_t> verify_hotp(uint32_t otp, uint64_t starting_counter, size_t resync_range = 0);+   private:+      std::unique_ptr<MessageAuthenticationCode> m_mac;+      uint32_t m_digit_mod;+   };++/**+* TOTP (time based) one time passwords (RFC 6238)+*/+class BOTAN_PUBLIC_API(2,2) TOTP final+   {+   public:+      /**+      * @param key the secret key shared between client and server+      * @param hash_algo the hash algorithm to use, should be SHA-1, SHA-256 or SHA-512+      * @param digits the number of digits in the OTP (must be 6, 7, or 8)+      * @param time_step granularity of OTP in seconds+      */+      TOTP(const SymmetricKey& key,+           const std::string& hash_algo = "SHA-1",+           size_t digits = 6, size_t time_step = 30) :+         TOTP(key.begin(), key.size(), hash_algo, digits, time_step) {}++      /**+      * @param key the secret key shared between client and server+      * @param key_len length of key+      * @param hash_algo the hash algorithm to use, should be SHA-1, SHA-256 or SHA-512+      * @param digits the number of digits in the OTP (must be 6, 7, or 8)+      * @param time_step granularity of OTP in seconds+      */+      TOTP(const uint8_t key[], size_t key_len,+           const std::string& hash_algo = "SHA-1",+           size_t digits = 6,+           size_t time_step = 30);++      /**+      * Convert the provided time_point to a Unix timestamp and call generate_totp+      */+      uint32_t generate_totp(std::chrono::system_clock::time_point time_point);++      /**+      * Generate the OTP corresponding the the provided "Unix timestamp" (ie+      * number of seconds since midnight Jan 1, 1970)+      */+      uint32_t generate_totp(uint64_t unix_time);++      bool verify_totp(uint32_t otp,+                       std::chrono::system_clock::time_point time,+                       size_t clock_drift_accepted = 0);++      bool verify_totp(uint32_t otp, uint64_t unix_time,+                       size_t clock_drift_accepted = 0);++   private:+      HOTP m_hotp;+      size_t m_time_step;+      std::chrono::system_clock::time_point m_unix_epoch;+   };++}++#endif
third_party/botan/src/lib/misc/hotp/totp.cpp view
@@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/totp.h>+#include <botan/otp.h> #include <botan/calendar.h>  namespace Botan {
third_party/botan/src/lib/misc/hotp/totp.h view
@@ -7,64 +7,7 @@ #ifndef BOTAN_TOTP_H_ #define BOTAN_TOTP_H_ -#include <botan/hotp.h>-#include <chrono>--namespace Botan {--/**-* TOTP (time based) one time passwords (RFC 6238)-*/-class BOTAN_PUBLIC_API(2,2) TOTP final-   {-   public:-      /**-      * @param key the secret key shared between client and server-      * @param hash_algo the hash algorithm to use, should be SHA-1, SHA-256 or SHA-512-      * @param digits the number of digits in the OTP (must be 6, 7, or 8)-      * @param time_step granularity of OTP in seconds-      */-      TOTP(const SymmetricKey& key,-           const std::string& hash_algo = "SHA-1",-           size_t digits = 6, size_t time_step = 30) :-         TOTP(key.begin(), key.size(), hash_algo, digits, time_step) {}--      /**-      * @param key the secret key shared between client and server-      * @param key_len length of key-      * @param hash_algo the hash algorithm to use, should be SHA-1, SHA-256 or SHA-512-      * @param digits the number of digits in the OTP (must be 6, 7, or 8)-      * @param time_step granularity of OTP in seconds-      */-      TOTP(const uint8_t key[], size_t key_len,-           const std::string& hash_algo = "SHA-1",-           size_t digits = 6,-           size_t time_step = 30);--      /**-      * Convert the provided time_point to a Unix timestamp and call generate_totp-      */-      uint32_t generate_totp(std::chrono::system_clock::time_point time_point);--      /**-      * Generate the OTP corresponding the the provided "Unix timestamp" (ie-      * number of seconds since midnight Jan 1, 1970)-      */-      uint32_t generate_totp(uint64_t unix_time);--      bool verify_totp(uint32_t otp,-                       std::chrono::system_clock::time_point time,-                       size_t clock_drift_accepted = 0);--      bool verify_totp(uint32_t otp, uint64_t unix_time,-                       size_t clock_drift_accepted = 0);--   private:-      HOTP m_hotp;-      size_t m_time_step;-      std::chrono::system_clock::time_point m_unix_epoch;-   };--}+#include <botan/otp.h>+BOTAN_DEPRECATED_HEADER(totp.h)  #endif
third_party/botan/src/lib/modes/aead/aead.cpp view
@@ -39,6 +39,14 @@  namespace Botan { +void AEAD_Mode::set_associated_data_n(size_t i, const uint8_t ad[], size_t ad_len)+   {+   if(i == 0)+      this->set_associated_data(ad, ad_len);+   else+      throw Invalid_Argument("AEAD '" + name() + "' does not support multiple associated data");+   }+ std::unique_ptr<AEAD_Mode> AEAD_Mode::create_or_throw(const std::string& algo,                                                       Cipher_Dir dir,                                                       const std::string& provider)
third_party/botan/src/lib/modes/aead/aead.h view
@@ -61,6 +61,32 @@       virtual void set_associated_data(const uint8_t ad[], size_t ad_len) = 0;        /**+      * Set associated data that is not included in the ciphertext but+      * that should be authenticated. Must be called after set_key and+      * before start.+      *+      * Unless reset by another call, the associated data is kept+      * between messages. Thus, if the AD does not change, calling+      * once (after set_key) is the optimum.+      *+      * Some AEADs (namely SIV) support multiple AD inputs. For+      * all other modes only nominal AD input 0 is supported; all+      * other values of i will cause an exception.+      *+      * @param ad the associated data+      * @param ad_len length of add in bytes+      */+      virtual void set_associated_data_n(size_t i, const uint8_t ad[], size_t ad_len);++      /**+      * Returns the maximum supported number of associated data inputs which+      * can be provided to set_associated_data_n+      *+      * If returns 0, then no associated data is supported.+      */+      virtual size_t maximum_associated_data_inputs() const { return 1; }++      /**       * Most AEADs require the key to be set prior to setting the AD       * A few allow the AD to be set even before the cipher is keyed.       * Such ciphers would return false from this function.
third_party/botan/src/lib/modes/aead/siv/siv.cpp view
@@ -78,9 +78,14 @@    m_ad_macs.clear();    } +size_t SIV_Mode::maximum_associated_data_inputs() const+   {+   return block_size() * 8 - 2;+   }+ void SIV_Mode::set_associated_data_n(size_t n, const uint8_t ad[], size_t length)    {-   const size_t max_ads = block_size() * 8 - 2;+   const size_t max_ads = maximum_associated_data_inputs();    if(n > max_ads)       throw Invalid_Argument(name() + " allows no more than " + std::to_string(max_ads) + " ADs"); 
third_party/botan/src/lib/modes/aead/siv/siv.h view
@@ -33,7 +33,9 @@       * @param ad associated data       * @param ad_len length of associated data in bytes       */-      void set_associated_data_n(size_t n, const uint8_t ad[], size_t ad_len);+      void set_associated_data_n(size_t n, const uint8_t ad[], size_t ad_len) override;++      size_t maximum_associated_data_inputs() const override;        void set_associated_data(const uint8_t ad[], size_t ad_len) override          {
third_party/botan/src/lib/pk_pad/emsa.h view
@@ -9,7 +9,7 @@ #define BOTAN_PUBKEY_EMSA_H_  #include <botan/secmem.h>-#include <botan/alg_id.h>+#include <botan/asn1_obj.h> #include <string>  BOTAN_FUTURE_INTERNAL_HEADER(emsa.h)
third_party/botan/src/lib/prov/commoncrypto/commoncrypto_utils.h view
@@ -8,7 +8,7 @@ #ifndef BOTAN_INTERNAL_COMMONCRYPTO_UTILS_H_ #define BOTAN_INTERNAL_COMMONCRYPTO_UTILS_H_ -#include <botan/key_spec.h>+#include <botan/sym_algo.h>  #include <CommonCrypto/CommonCrypto.h> 
third_party/botan/src/lib/prov/pkcs11/info.txt view
@@ -24,11 +24,13 @@ p11_ecc_key.h p11_ecdh.h p11_ecdsa.h-p11_module.h p11_object.h p11_randomgenerator.h p11_rsa.h-p11_session.h-p11_slot.h+p11_types.h p11_x509.h++p11_module.h+p11_slot.h+p11_session.h </header:public>
third_party/botan/src/lib/prov/pkcs11/p11.cpp view
@@ -7,7 +7,8 @@ */  #include <botan/p11.h>-#include <botan/p11_session.h>+#include <botan/p11_types.h>+#include <botan/dyn_load.h>  #include <cstdint> #include <string>
third_party/botan/src/lib/prov/pkcs11/p11.h view
@@ -11,7 +11,6 @@  #include <botan/secmem.h> #include <botan/exceptn.h>-#include <botan/dyn_load.h>  #include <vector> #include <string>@@ -56,6 +55,9 @@               "The Botan PKCS#11 module was implemented against PKCS#11 v2.40. Please use the correct PKCS#11 headers.");  namespace Botan {++class Dynamically_Loaded_Library;+ namespace PKCS11 {  using secure_string = secure_vector<uint8_t>;
third_party/botan/src/lib/prov/pkcs11/p11_ecc_key.h view
@@ -15,7 +15,7 @@ #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) #include <botan/ecc_key.h> #include <botan/ec_group.h>-#include <botan/alg_id.h>+#include <botan/asn1_obj.h> #include <vector>  namespace Botan {
third_party/botan/src/lib/prov/pkcs11/p11_module.cpp view
@@ -6,11 +6,14 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/p11_module.h>+#include <botan/p11_types.h>+#include <botan/dyn_load.h>  namespace Botan {  namespace PKCS11 {++Module::Module(Module&&) = default;  Module::Module(const std::string& file_path, C_InitializeArgs init_args)    : m_file_path(file_path)
third_party/botan/src/lib/prov/pkcs11/p11_module.h view
@@ -9,67 +9,7 @@ #ifndef BOTAN_P11_MODULE_H_ #define BOTAN_P11_MODULE_H_ -#include <string>-#include <memory>--#include <botan/p11.h>-#include <botan/dyn_load.h>--namespace Botan {-namespace PKCS11 {--/**-* Loads the PKCS#11 shared library-* Calls C_Initialize on load and C_Finalize on destruction-*/-class BOTAN_PUBLIC_API(2,0) Module final-   {-   public:-      /**-      * Loads the shared library and calls C_Initialize-      * @param file_path the path to the PKCS#11 shared library-      * @param init_args flags to use for `C_Initialize`-      */-      Module(const std::string& file_path, C_InitializeArgs init_args = { nullptr, nullptr, nullptr, nullptr, static_cast< CK_FLAGS >(Flag::OsLockingOk), nullptr });--      Module(Module&& other) = default;-      Module& operator=(Module&& other) = delete;--      // Dtor calls C_Finalize(). A copy could be deleted while the origin still exists-      // Furthermore std::unique_ptr member -> not copyable-      Module(const Module& other) = delete;-      Module& operator=(const Module& other) = delete;--      /// Calls C_Finalize()-      ~Module() noexcept;--      /**-      * Reloads the module and reinitializes it-      * @param init_args flags to use for `C_Initialize`-      */-      void reload(C_InitializeArgs init_args = { nullptr, nullptr, nullptr, nullptr, static_cast< CK_FLAGS >(Flag::OsLockingOk), nullptr });--      inline LowLevel* operator->() const-         {-         return m_low_level.get();-         }--      /// @return general information about Cryptoki-      inline Info get_info() const-         {-         Info info;-         m_low_level->C_GetInfo(&info);-         return info;-         }--   private:-      const std::string m_file_path;-      FunctionListPtr m_func_list = nullptr;-      std::unique_ptr<Dynamically_Loaded_Library> m_library = nullptr;-      std::unique_ptr<LowLevel> m_low_level = nullptr;-   };--}-}+#include <botan/p11_types.h>+BOTAN_DEPRECATED_HEADER(p11_module.h)  #endif
third_party/botan/src/lib/prov/pkcs11/p11_object.h view
@@ -10,7 +10,7 @@ #define BOTAN_P11_OBJECT_H_  #include <botan/p11.h>-#include <botan/p11_session.h>+#include <botan/p11_types.h> #include <botan/secmem.h>  #include <vector>
third_party/botan/src/lib/prov/pkcs11/p11_randomgenerator.h view
@@ -10,7 +10,7 @@ #define BOTAN_P11_RNG_H_  #include <botan/rng.h>-#include <botan/p11_session.h>+#include <botan/p11_types.h> #include <botan/entropy_src.h>  #include <string>
third_party/botan/src/lib/prov/pkcs11/p11_rsa.h view
@@ -9,7 +9,7 @@ #ifndef BOTAN_P11_RSA_H_ #define BOTAN_P11_RSA_H_ -#include <botan/p11_session.h>+#include <botan/p11_types.h> #include <botan/p11_object.h> #include <botan/pk_keys.h> #include <botan/bigint.h>
third_party/botan/src/lib/prov/pkcs11/p11_session.cpp view
@@ -6,7 +6,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/p11_session.h>+#include <botan/p11_types.h>  namespace Botan { namespace PKCS11 {
third_party/botan/src/lib/prov/pkcs11/p11_session.h view
@@ -9,92 +9,7 @@ #ifndef BOTAN_P11_SESSION_H_ #define BOTAN_P11_SESSION_H_ -#include <botan/p11_slot.h>--#include <utility>--namespace Botan {-namespace PKCS11 {-class Module;--/// Represents a PKCS#11 session-class BOTAN_PUBLIC_API(2,0) Session final-   {-   public:-      /**-      * @param slot the slot to use-      * @param read_only true if the session should be read only, false to create a read-write session-      */-      Session(Slot& slot, bool read_only);--      /**-      * @param slot the slot to use-      * @param flags the flags to use for the session. Remark: Flag::SerialSession is mandatory-      * @param callback_data application-defined pointer to be passed to the notification callback-      * @param notify_callback address of the notification callback function-      */-      Session(Slot& slot, Flags flags, VoidPtr callback_data, Notify notify_callback);--      /// Takes ownership of a session-      Session(Slot& slot, SessionHandle handle);--      Session(Session&& other) = default;-      Session& operator=(Session&& other) = delete;--      // Dtor calls C_CloseSession() and eventually C_Logout. A copy could close the session while the origin still exists-      Session(const Session& other) = delete;-      Session& operator=(const Session& other) = delete;--      /// Logout user and close the session on destruction-      ~Session() noexcept;--      /// @return a reference to the slot-      inline const Slot& slot() const-         {-         return m_slot;-         }--      /// @return the session handle of this session-      inline SessionHandle handle() const-         {-         return m_handle;-         }--      /// @return a reference to the used module-      inline Module& module() const-         {-         return m_slot.module();-         }--      /// @return the released session handle-      SessionHandle release();--      /**-      * Login to this session-      * @param userType the user type to use for the login-      * @param pin the PIN of the user-      */-      void login(UserType userType, const secure_string& pin);--      /// Logout from this session-      void logoff();--      /// @return information about this session-      SessionInfo get_info() const;--      /// Calls `C_SetPIN` to change the PIN using the old PIN (requires a logged in session)-      void set_pin(const secure_string& old_pin, const secure_string& new_pin) const;--      /// Calls `C_InitPIN` to change or initialize the PIN using the SO_PIN (requires a logged in session)-      void init_pin(const secure_string& new_pin);--   private:-      const Slot& m_slot;-      SessionHandle m_handle;-      bool m_logged_in;-   };--}-}+#include <botan/p11_types.h>+BOTAN_DEPRECATED_HEADER(p11_session.h)  #endif
third_party/botan/src/lib/prov/pkcs11/p11_slot.cpp view
@@ -6,7 +6,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/p11_slot.h>+#include <botan/p11_types.h>  namespace Botan { 
third_party/botan/src/lib/prov/pkcs11/p11_slot.h view
@@ -9,70 +9,7 @@ #ifndef BOTAN_P11_SLOT_H_ #define BOTAN_P11_SLOT_H_ -#include <string>-#include <vector>-#include <functional>--#include <botan/p11_module.h>--namespace Botan {-namespace PKCS11 {--/// Represents a PKCS#11 Slot, i.e., a card reader-class BOTAN_PUBLIC_API(2,0) Slot final-   {-   public:-      /**-      * @param module the PKCS#11 module to use-      * @param slot_id the slot id to use-      */-      Slot(Module& module, SlotId slot_id);--      /// @return a reference to the module that is used-      inline Module& module() const-         {-         return m_module;-         }--      /// @return the slot id-      inline SlotId slot_id() const-         {-         return m_slot_id;-         }--      /**-      * Get available slots-      * @param module the module to use-      * @param token_present true if only slots with attached tokens should be returned, false for all slots-      * @return a list of available slots (calls C_GetSlotList)-      */-      static std::vector<SlotId> get_available_slots(Module& module, bool token_present);--      /// @return information about the slot (`C_GetSlotInfo`)-      SlotInfo get_slot_info() const;--      /// Obtains a list of mechanism types supported by the slot (`C_GetMechanismList`)-      std::vector<MechanismType> get_mechanism_list() const;--      /// Obtains information about a particular mechanism possibly supported by a slot (`C_GetMechanismInfo`)-      MechanismInfo get_mechanism_info(MechanismType mechanism_type) const;--      /// Obtains information about a particular token in the system (`C_GetTokenInfo`)-      TokenInfo get_token_info() const;--      /**-      * Calls `C_InitToken` to initialize the token-      * @param label the label for the token (must not exceed 32 bytes according to PKCS#11)-      * @param so_pin the PIN of the security officer-      */-      void initialize(const std::string& label, const secure_string& so_pin) const;--   private:-      const std::reference_wrapper<Module> m_module;-      const SlotId m_slot_id;-   };--}-}+#include <botan/p11_types.h>+BOTAN_DEPRECATED_HEADER(p11_slot.h)  #endif
+ third_party/botan/src/lib/prov/pkcs11/p11_types.h view
@@ -0,0 +1,209 @@+/*+* PKCS#11 Module/Slot/Session+* (C) 2016 Daniel Neus, Sirrix AG+* (C) 2016 Philipp Weber, Sirrix AG+*+* Botan is released under the Simplified BSD License (see license.txt)+*/++#ifndef BOTAN_P11_TYPES_H_+#define BOTAN_P11_TYPES_H_++#include <botan/p11.h>+#include <string>+#include <memory>+#include <functional>+#include <utility>++namespace Botan {++class Dynamically_Loaded_Library;++namespace PKCS11 {++/**+* Loads the PKCS#11 shared library+* Calls C_Initialize on load and C_Finalize on destruction+*/+class BOTAN_PUBLIC_API(2,0) Module final+   {+   public:+      /**+      * Loads the shared library and calls C_Initialize+      * @param file_path the path to the PKCS#11 shared library+      * @param init_args flags to use for `C_Initialize`+      */+      Module(const std::string& file_path, C_InitializeArgs init_args = { nullptr, nullptr, nullptr, nullptr, static_cast< CK_FLAGS >(Flag::OsLockingOk), nullptr });++      Module(Module&& other);+      Module& operator=(Module&& other) = delete;++      // Dtor calls C_Finalize(). A copy could be deleted while the origin still exists+      // Furthermore std::unique_ptr member -> not copyable+      Module(const Module& other) = delete;+      Module& operator=(const Module& other) = delete;++      /// Calls C_Finalize()+      ~Module() noexcept;++      /**+      * Reloads the module and reinitializes it+      * @param init_args flags to use for `C_Initialize`+      */+      void reload(C_InitializeArgs init_args = { nullptr, nullptr, nullptr, nullptr, static_cast< CK_FLAGS >(Flag::OsLockingOk), nullptr });++      inline LowLevel* operator->() const+         {+         return m_low_level.get();+         }++      /// @return general information about Cryptoki+      inline Info get_info() const+         {+         Info info;+         m_low_level->C_GetInfo(&info);+         return info;+         }++   private:+      const std::string m_file_path;+      FunctionListPtr m_func_list = nullptr;+      std::unique_ptr<Dynamically_Loaded_Library> m_library;+      std::unique_ptr<LowLevel> m_low_level = nullptr;+   };++/// Represents a PKCS#11 Slot, i.e., a card reader+class BOTAN_PUBLIC_API(2,0) Slot final+   {+   public:+      /**+      * @param module the PKCS#11 module to use+      * @param slot_id the slot id to use+      */+      Slot(Module& module, SlotId slot_id);++      /// @return a reference to the module that is used+      inline Module& module() const+         {+         return m_module;+         }++      /// @return the slot id+      inline SlotId slot_id() const+         {+         return m_slot_id;+         }++      /**+      * Get available slots+      * @param module the module to use+      * @param token_present true if only slots with attached tokens should be returned, false for all slots+      * @return a list of available slots (calls C_GetSlotList)+      */+      static std::vector<SlotId> get_available_slots(Module& module, bool token_present);++      /// @return information about the slot (`C_GetSlotInfo`)+      SlotInfo get_slot_info() const;++      /// Obtains a list of mechanism types supported by the slot (`C_GetMechanismList`)+      std::vector<MechanismType> get_mechanism_list() const;++      /// Obtains information about a particular mechanism possibly supported by a slot (`C_GetMechanismInfo`)+      MechanismInfo get_mechanism_info(MechanismType mechanism_type) const;++      /// Obtains information about a particular token in the system (`C_GetTokenInfo`)+      TokenInfo get_token_info() const;++      /**+      * Calls `C_InitToken` to initialize the token+      * @param label the label for the token (must not exceed 32 bytes according to PKCS#11)+      * @param so_pin the PIN of the security officer+      */+      void initialize(const std::string& label, const secure_string& so_pin) const;++   private:+      const std::reference_wrapper<Module> m_module;+      const SlotId m_slot_id;+   };++/// Represents a PKCS#11 session+class BOTAN_PUBLIC_API(2,0) Session final+   {+   public:+      /**+      * @param slot the slot to use+      * @param read_only true if the session should be read only, false to create a read-write session+      */+      Session(Slot& slot, bool read_only);++      /**+      * @param slot the slot to use+      * @param flags the flags to use for the session. Remark: Flag::SerialSession is mandatory+      * @param callback_data application-defined pointer to be passed to the notification callback+      * @param notify_callback address of the notification callback function+      */+      Session(Slot& slot, Flags flags, VoidPtr callback_data, Notify notify_callback);++      /// Takes ownership of a session+      Session(Slot& slot, SessionHandle handle);++      Session(Session&& other) = default;+      Session& operator=(Session&& other) = delete;++      // Dtor calls C_CloseSession() and eventually C_Logout. A copy could close the session while the origin still exists+      Session(const Session& other) = delete;+      Session& operator=(const Session& other) = delete;++      /// Logout user and close the session on destruction+      ~Session() noexcept;++      /// @return a reference to the slot+      inline const Slot& slot() const+         {+         return m_slot;+         }++      /// @return the session handle of this session+      inline SessionHandle handle() const+         {+         return m_handle;+         }++      /// @return a reference to the used module+      inline Module& module() const+         {+         return m_slot.module();+         }++      /// @return the released session handle+      SessionHandle release();++      /**+      * Login to this session+      * @param userType the user type to use for the login+      * @param pin the PIN of the user+      */+      void login(UserType userType, const secure_string& pin);++      /// Logout from this session+      void logoff();++      /// @return information about this session+      SessionInfo get_info() const;++      /// Calls `C_SetPIN` to change the PIN using the old PIN (requires a logged in session)+      void set_pin(const secure_string& old_pin, const secure_string& new_pin) const;++      /// Calls `C_InitPIN` to change or initialize the PIN using the SO_PIN (requires a logged in session)+      void init_pin(const secure_string& new_pin);++   private:+      const Slot& m_slot;+      SessionHandle m_handle;+      bool m_logged_in;+   };++}+}++#endif
third_party/botan/src/lib/psk_db/psk_db.h view
@@ -141,6 +141,26 @@       secure_vector<uint8_t> m_wrap_key;    }; +class SQL_Database;++class BOTAN_PUBLIC_API(2,4) Encrypted_PSK_Database_SQL : public Encrypted_PSK_Database+   {+   public:+      Encrypted_PSK_Database_SQL(const secure_vector<uint8_t>& master_key,+                                 std::shared_ptr<SQL_Database> db,+                                 const std::string& table_name);++      ~Encrypted_PSK_Database_SQL();+   private:+      void kv_set(const std::string& index, const std::string& value) override;+      std::string kv_get(const std::string& index) const override;+      void kv_del(const std::string& index) override;+      std::set<std::string> kv_get_all() const override;++      std::shared_ptr<SQL_Database> m_db;+      const std::string m_table_name;+   };+ }  #endif
third_party/botan/src/lib/psk_db/psk_db_sql.cpp view
@@ -4,7 +4,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/psk_db_sql.h>+#include <botan/psk_db.h>+#include <botan/database.h>  namespace Botan { @@ -18,6 +19,11 @@    m_db->create_table(       "create table if not exists " + m_table_name +       "(psk_name TEXT PRIMARY KEY, psk_value TEXT)");+   }++Encrypted_PSK_Database_SQL::~Encrypted_PSK_Database_SQL()+   {+   /* for ~unique_ptr */    }  void Encrypted_PSK_Database_SQL::kv_del(const std::string& name)
third_party/botan/src/lib/psk_db/psk_db_sql.h view
@@ -8,27 +8,6 @@ #define BOTAN_PSK_DB_SQL_H_  #include <botan/psk_db.h>-#include <botan/database.h>--namespace Botan {--class BOTAN_PUBLIC_API(2,4) Encrypted_PSK_Database_SQL : public Encrypted_PSK_Database-   {-   public:-      Encrypted_PSK_Database_SQL(const secure_vector<uint8_t>& master_key,-                                 std::shared_ptr<SQL_Database> db,-                                 const std::string& table_name);--   private:-      void kv_set(const std::string& index, const std::string& value) override;-      std::string kv_get(const std::string& index) const override;-      void kv_del(const std::string& index) override;-      std::set<std::string> kv_get_all() const override;--      std::shared_ptr<SQL_Database> m_db;-      const std::string m_table_name;-   };--}+BOTAN_DEPRECATED_HEADER(psk_db_sql.h)  #endif
third_party/botan/src/lib/pubkey/dl_group/dl_group.cpp view
@@ -9,6 +9,7 @@ #include <botan/numthry.h> #include <botan/reducer.h> #include <botan/monty.h>+#include <botan/divide.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/pem.h>@@ -214,9 +215,10 @@ */ BigInt make_dsa_generator(const BigInt& p, const BigInt& q)    {-   const BigInt e = (p - 1) / q;+   BigInt e, r;+   vartime_divide(p - 1, q, e, r); -   if(e == 0 || (p - 1) % q > 0)+   if(e == 0 || r > 0)       throw Invalid_Argument("make_dsa_generator q does not divide p-1");     for(size_t i = 0; i != PRIME_TABLE_SIZE; ++i)
third_party/botan/src/lib/pubkey/ec_group/ec_group.h view
@@ -11,7 +11,7 @@ #define BOTAN_ECC_DOMAIN_PARAMETERS_H_  #include <botan/point_gfp.h>-#include <botan/asn1_oid.h>+#include <botan/asn1_obj.h> #include <memory> #include <set> 
third_party/botan/src/lib/pubkey/ec_group/point_gfp.cpp view
@@ -427,6 +427,12 @@       return;       } +   for(size_t i = 0; i != points.size(); ++i)+      {+      if(points[i].is_zero())+         throw Invalid_State("Cannot convert zero ECC point to affine");+      }+    /*    For >= 2 points use Montgomery's trick 
third_party/botan/src/lib/pubkey/ec_group/point_mul.cpp view
@@ -9,6 +9,7 @@ #include <botan/reducer.h> #include <botan/internal/rounding.h> #include <botan/internal/ct_utils.h>+#include <iostream>  namespace Botan { @@ -375,7 +376,19 @@    m_M.push_back(y3.plus(x2, ws));    m_M.push_back(y3.plus(x3, ws)); -   PointGFp::force_all_affine(m_M, ws[0].get_word_vector());+   bool no_infinity = true;+   for(auto& pt : m_M)+      {+      if(pt.is_zero())+         no_infinity = false;+      }++   if(no_infinity)+      {+      PointGFp::force_all_affine(m_M, ws[0].get_word_vector());+      }++   m_no_infinity = no_infinity;    }  PointGFp PointGFp_Multi_Point_Precompute::multi_exp(const BigInt& z1,@@ -402,7 +415,10 @@       // This function is not intended to be const time       if(z12)          {-         H.add_affine(m_M[z12-1], ws);+         if(m_no_infinity)+            H.add_affine(m_M[z12-1], ws);+         else+            H.add(m_M[z12-1], ws);          }       } 
third_party/botan/src/lib/pubkey/ec_group/point_mul.h view
@@ -77,6 +77,7 @@                          const BigInt& k2) const;    private:       std::vector<PointGFp> m_M;+      bool m_no_infinity;    };  }
third_party/botan/src/lib/pubkey/mce/code_based_key_gen.cpp view
@@ -13,6 +13,7 @@ #include <botan/mceliece.h> #include <botan/internal/mce_internal.h> #include <botan/internal/code_based_util.h>+#include <botan/polyn_gf2m.h> #include <botan/loadstor.h>  namespace Botan {
third_party/botan/src/lib/pubkey/mce/gf2m_small_m.h view
@@ -15,8 +15,7 @@ #include <botan/types.h> #include <vector> -// fixme - still used in mceliece.h-//BOTAN_FUTURE_INTERNAL_HEADER(gf2m_small_m.h)+BOTAN_FUTURE_INTERNAL_HEADER(gf2m_small_m.h)  namespace Botan { 
third_party/botan/src/lib/pubkey/mce/mce_internal.h view
@@ -16,6 +16,7 @@ #include <botan/types.h> #include <botan/pk_ops.h> #include <botan/mceliece.h>+#include <botan/polyn_gf2m.h>  namespace Botan { 
third_party/botan/src/lib/pubkey/mce/mceliece.h view
@@ -14,10 +14,13 @@  #include <botan/pk_keys.h> #include <botan/polyn_gf2m.h>-#include <botan/exceptn.h>  namespace Botan { +typedef uint16_t gf2m;++class polyn_gf2m;+ class BOTAN_PUBLIC_API(2,0) McEliece_PublicKey : public virtual Public_Key    {    public:@@ -94,9 +97,11 @@                           std::vector<gf2m> const& inverse_support,                           std::vector<uint8_t> const& public_matrix ); +      ~McEliece_PrivateKey();+       bool check_key(RandomNumberGenerator& rng, bool strong) const override; -      polyn_gf2m const& get_goppa_polyn() const { return m_g; }+      polyn_gf2m const& get_goppa_polyn() const;       std::vector<uint32_t> const& get_H_coeffs() const { return m_coeffs; }       std::vector<gf2m> const& get_Linv() const { return m_Linv; }       std::vector<polyn_gf2m> const& get_sqrtmod() const { return m_sqrtmod; }@@ -116,7 +121,7 @@                                   const std::string& params,                                   const std::string& provider) const override;    private:-      polyn_gf2m m_g;+      std::vector<polyn_gf2m> m_g; // single element       std::vector<polyn_gf2m> m_sqrtmod;       std::vector<gf2m> m_Linv;       std::vector<uint32_t> m_coeffs;
third_party/botan/src/lib/pubkey/mce/mceliece_key.cpp view
@@ -11,6 +11,7 @@  */  #include <botan/mceliece.h>+#include <botan/polyn_gf2m.h> #include <botan/internal/mce_internal.h> #include <botan/internal/bit_ops.h> #include <botan/internal/code_based_util.h>@@ -28,7 +29,7 @@                                          std::vector<gf2m> const& inverse_support,                                          std::vector<uint8_t> const& public_matrix) :    McEliece_PublicKey(public_matrix, goppa_polyn.get_degree(), inverse_support.size()),-   m_g(goppa_polyn),+   m_g{goppa_polyn},    m_sqrtmod(square_root_matrix),    m_Linv(inverse_support),    m_coeffs(parity_check_matrix_coeffs),@@ -43,6 +44,13 @@    *this = generate_mceliece_key(rng, ext_deg, code_length, t);    } +McEliece_PrivateKey::~McEliece_PrivateKey() = default;++const polyn_gf2m& McEliece_PrivateKey::get_goppa_polyn() const+   {+   return m_g[0];+   }+ size_t McEliece_PublicKey::get_message_word_bit_length() const    {    size_t codimension = ceil_log2(m_code_length) * m_t;@@ -120,7 +128,7 @@       .encode(static_cast<size_t>(get_t()))       .end_cons()       .encode(m_public_matrix, OCTET_STRING)-      .encode(m_g.encode(), OCTET_STRING); // g as octet string+      .encode(m_g[0].encode(), OCTET_STRING); // g as octet string    enc.start_cons(SEQUENCE);    for(size_t i = 0; i < m_sqrtmod.size(); i++)       {@@ -189,8 +197,8 @@    m_dimension = (n - m_codimension);     std::shared_ptr<GF2m_Field> sp_field(new GF2m_Field(ext_deg));-   m_g = polyn_gf2m(enc_g, sp_field);-   if(m_g.get_degree() != static_cast<int>(t))+   m_g = { polyn_gf2m(enc_g, sp_field) };+   if(m_g[0].get_degree() != static_cast<int>(t))       {       throw Decoding_Error("degree of decoded Goppa polynomial is incorrect");       }
third_party/botan/src/lib/pubkey/mce/polyn_gf2m.h view
@@ -13,13 +13,17 @@ #define BOTAN_POLYN_GF2M_H_  #include <botan/secmem.h>-#include <botan/gf2m_small_m.h> #include <utility> #include <string> +// Currently must be visible for MSVC //BOTAN_FUTURE_INTERNAL_HEADER(polyn_gf2m.h)  namespace Botan {++typedef uint16_t gf2m;++class GF2m_Field;  class RandomNumberGenerator; 
third_party/botan/src/lib/pubkey/pbes2/pbes2.cpp view
@@ -13,7 +13,7 @@ #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/parsing.h>-#include <botan/alg_id.h>+#include <botan/asn1_obj.h> #include <botan/oids.h> #include <botan/rng.h> 
third_party/botan/src/lib/pubkey/pbes2/pbes2.h view
@@ -8,7 +8,7 @@ #ifndef BOTAN_PBE_PKCS_v20_H_ #define BOTAN_PBE_PKCS_v20_H_ -#include <botan/alg_id.h>+#include <botan/asn1_obj.h> #include <chrono>  BOTAN_FUTURE_INTERNAL_HEADER(pbes2.h)
third_party/botan/src/lib/pubkey/pk_algs.h view
@@ -9,7 +9,7 @@ #define BOTAN_PK_KEY_FACTORY_H_  #include <botan/pk_keys.h>-#include <botan/alg_id.h>+#include <botan/asn1_obj.h> #include <memory>  namespace Botan {
third_party/botan/src/lib/pubkey/pk_keys.h view
@@ -9,8 +9,7 @@ #define BOTAN_PK_KEYS_H_  #include <botan/secmem.h>-#include <botan/asn1_oid.h>-#include <botan/alg_id.h>+#include <botan/asn1_obj.h> #include <botan/pk_ops_fwd.h> #include <string> 
third_party/botan/src/lib/pubkey/pkcs8.cpp view
@@ -9,7 +9,7 @@ #include <botan/rng.h> #include <botan/der_enc.h> #include <botan/ber_dec.h>-#include <botan/alg_id.h>+#include <botan/asn1_obj.h> #include <botan/oids.h> #include <botan/pem.h> #include <botan/scan_name.h>
third_party/botan/src/lib/pubkey/rsa/rsa.cpp view
@@ -291,6 +291,10 @@       // TODO could generate primes in thread pool       p = generate_rsa_prime(rng, rng, p_bits, e);       q = generate_rsa_prime(rng, rng, q_bits, e);++      if(p == q)+         throw Internal_Error("RNG failure during RSA key generation");+       n = p * q;       } while(n.bits() != bits); @@ -321,6 +325,9 @@       return false;     if(get_p() * get_q() != get_n())+      return false;++   if(get_p() == get_q())       return false;     if(get_d1() != ct_modulo(get_d(), get_p() - 1))
third_party/botan/src/lib/pubkey/workfactor.h view
@@ -9,6 +9,7 @@ #define BOTAN_WORKFACTOR_H_  #include <botan/types.h>+BOTAN_FUTURE_INTERNAL_HEADER(workfactor.h)  namespace Botan { 
third_party/botan/src/lib/pubkey/x509_key.cpp view
@@ -9,7 +9,7 @@ #include <botan/data_src.h> #include <botan/ber_dec.h> #include <botan/pem.h>-#include <botan/alg_id.h>+#include <botan/asn1_obj.h> #include <botan/pk_algs.h>  namespace Botan {
third_party/botan/src/lib/pubkey/xmss/info.txt view
@@ -1,32 +1,31 @@ <defines>-XMSS_RFC8391 -> 20190623+XMSS_RFC8391 -> 20201101 </defines>  <header:public>-atomic.h xmss.h xmss_hash.h-xmss_index_registry.h-xmss_address.h+xmss_wots.h xmss_parameters.h xmss_key_pair.h xmss_privatekey.h xmss_publickey.h-xmss_tools.h xmss_wots_parameters.h xmss_wots_privatekey.h xmss_wots_publickey.h--# future internal:-xmss_common_ops.h </header:public>  <header:internal>-xmss_wots_addressed_privatekey.h-xmss_wots_addressed_publickey.h+atomic.h+xmss_address.h+xmss_common_ops.h+xmss_index_registry.h xmss_signature.h xmss_signature_operation.h+xmss_tools.h xmss_verification_operation.h+xmss_wots_addressed_privatekey.h+xmss_wots_addressed_publickey.h </header:internal>  <requires>
third_party/botan/src/lib/pubkey/xmss/xmss.h view
@@ -1,26 +1,459 @@+/*+ * XMSS Keys+ * (C) 2016,2017 Matthias Gierlings+ * (C) 2019 René Korthaus, Rohde & Schwarz Cybersecurity+ *+ * Botan is released under the Simplified BSD License (see license.txt)+ **/++#ifndef BOTAN_XMSS_H_+#define BOTAN_XMSS_H_++#include <botan/pk_keys.h>+#include <botan/exceptn.h>+#include <botan/xmss_parameters.h>+#include <botan/xmss_wots.h>++namespace Botan {++class RandomNumberGenerator;+class XMSS_Verification_Operation;+ /**- * @file xmss.h- * Includes headers required for Extended Hash-Based Signatures (XMSS)- * as described in [1]. @see Botan::XMSS_PublicKey and @see- * Botan::XMSS_PrivateKey for further- * details.+ * An XMSS: Extended Hash-Based Signature public key.  *- * <pre>  * [1] XMSS: Extended Hash-Based Signatures,  *     Request for Comments: 8391  *     Release: May 2018.  *     https://datatracker.ietf.org/doc/rfc8391/- * </pre>- *- * (C) 2016,2017,2018 Matthias Gierlings+ **/+class BOTAN_PUBLIC_API(2,0) XMSS_PublicKey : public virtual Public_Key+   {+   public:+      /**+       * Creates a new XMSS public key for the chosen XMSS signature method.+       * New public and prf seeds are generated using rng. The appropriate WOTS+       * signature method will be automatically set based on the chosen XMSS+       * signature method.+       *+       * @param xmss_oid Identifier for the selected XMSS signature method.+       * @param rng A random number generator to use for key generation.+       **/+      XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,+                     RandomNumberGenerator& rng);++      /**+       * Loads a public key.+       *+       * Public key must be encoded as in RFC+       * draft-vangeest-x509-hash-sigs-03.+       *+       * @param key_bits DER encoded public key bits+       */+      XMSS_PublicKey(const std::vector<uint8_t>& key_bits);++      /**+       * Creates a new XMSS public key for a chosen XMSS signature method as+       * well as pre-computed root node and public_seed values.+       *+       * @param xmss_oid Identifier for the selected XMSS signature method.+       * @param root Root node value.+       * @param public_seed Public seed value.+       **/+      XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,+                     const secure_vector<uint8_t>& root,+                     const secure_vector<uint8_t>& public_seed)+         : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),+           m_root(root), m_public_seed(public_seed) {}++      /**+       * Creates a new XMSS public key for a chosen XMSS signature method as+       * well as pre-computed root node and public_seed values.+       *+       * @param xmss_oid Identifier for the selected XMSS signature method.+       * @param root Root node value.+       * @param public_seed Public seed value.+       **/+      XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,+                     secure_vector<uint8_t>&& root,+                     secure_vector<uint8_t>&& public_seed)+         : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),+           m_root(std::move(root)), m_public_seed(std::move(public_seed)) {}++      /**+       * Retrieves the chosen XMSS signature method.+       *+       * @return XMSS signature method identifier.+       **/+      XMSS_Parameters::xmss_algorithm_t xmss_oid() const+         {+         return m_xmss_params.oid();+         }++      /**+       * Sets the chosen XMSS signature method+       **/+      void set_xmss_oid(XMSS_Parameters::xmss_algorithm_t xmss_oid)+         {+         m_xmss_params = XMSS_Parameters(xmss_oid);+         m_wots_params = XMSS_WOTS_Parameters(m_xmss_params.ots_oid());+         }++      /**+       * Retrieves the XMSS parameters determined by the chosen XMSS Signature+       * method.+       *+       * @return XMSS parameters.+       **/+      const XMSS_Parameters& xmss_parameters() const+         {+         return m_xmss_params;+         }++      /**+       * Retrieves the XMSS parameters determined by the chosen XMSS Signature+       * method.+       *+       * @return XMSS parameters.+       **/+      std::string xmss_hash_function() const+         {+         return m_xmss_params.hash_function_name();+         }++      /**+       * Retrieves the Winternitz One Time Signature (WOTS) method,+       * corresponding to the chosen XMSS signature method.+       *+       * @return XMSS WOTS signature method identifier.+       **/+      XMSS_WOTS_Parameters::ots_algorithm_t wots_oid() const+         {+         return m_wots_params.oid();+         }++      /**+       * Retrieves the Winternitz One Time Signature (WOTS) parameters+       * corresponding to the chosen XMSS signature method.+       *+       * @return XMSS WOTS signature method parameters.+       **/+      const XMSS_WOTS_Parameters& wots_parameters() const+         {+         return m_wots_params;+         }++      secure_vector<uint8_t>& root()+         {+         return m_root;+         }++      void set_root(const secure_vector<uint8_t>& root)+         {+         m_root = root;+         }++      void set_root(secure_vector<uint8_t>&& root)+         {+         m_root = std::move(root);+         }++      const secure_vector<uint8_t>& root() const+         {+         return m_root;+         }++      virtual secure_vector<uint8_t>& public_seed()+         {+         return m_public_seed;+         }++      virtual void set_public_seed(const secure_vector<uint8_t>& public_seed)+         {+         m_public_seed = public_seed;+         }++      virtual void set_public_seed(secure_vector<uint8_t>&& public_seed)+         {+         m_public_seed = std::move(public_seed);+         }++      virtual const secure_vector<uint8_t>& public_seed() const+         {+         return m_public_seed;+         }++      std::string algo_name() const override+         {+         return "XMSS";+         }++      AlgorithmIdentifier algorithm_identifier() const override+         {+         return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_EMPTY_PARAM);+         }++      bool check_key(RandomNumberGenerator&, bool) const override+         {+         return true;+         }++      std::unique_ptr<PK_Ops::Verification>+      create_verification_op(const std::string&,+                             const std::string& provider) const override;++      size_t estimated_strength() const override+         {+         return m_xmss_params.estimated_strength();+         }++      size_t key_length() const override+         {+         return m_xmss_params.estimated_strength();+         }++      /**+       * Returns the encoded public key as defined in RFC+       * draft-vangeest-x509-hash-sigs-03.+       *+       * @return encoded public key bits+       **/+      std::vector<uint8_t> public_key_bits() const override;++      /**+       * Size in bytes of the serialized XMSS public key produced by+       * raw_public_key().+       *+       * @return size in bytes of serialized Public Key.+       **/+      virtual size_t size() const+         {+         return sizeof(uint32_t) + 2 * m_xmss_params.element_size();+         }++      /**+       * Generates a byte sequence representing the XMSS+       * public key, as defined in [1] (p. 23, "XMSS Public Key")+       *+       * @return 4-byte OID, followed by n-byte root node, followed by+       *         public seed.+       **/+      virtual std::vector<uint8_t> raw_public_key() const;++   protected:+      std::vector<uint8_t> m_raw_key;+      XMSS_Parameters m_xmss_params;+      XMSS_WOTS_Parameters m_wots_params;+      secure_vector<uint8_t> m_root;+      secure_vector<uint8_t> m_public_seed;++   private:+      XMSS_Parameters::xmss_algorithm_t deserialize_xmss_oid(+         const std::vector<uint8_t>& raw_key);+   };++template<typename> class Atomic;++class XMSS_Index_Registry;++/**+ * An XMSS: Extended Hash-Based Signature private key.+ * The XMSS private key does not support the X509 and PKCS7 standard. Instead+ * the raw format described in [1] is used.  *- * Botan is released under the Simplified BSD License (see license.txt)+ * [1] XMSS: Extended Hash-Based Signatures,+ *     Request for Comments: 8391+ *     Release: May 2018.+ *     https://datatracker.ietf.org/doc/rfc8391/  **/+class BOTAN_PUBLIC_API(2,0) XMSS_PrivateKey final : public virtual XMSS_PublicKey,+   public virtual Private_Key+   {+   public:+      /**+      * Creates a new XMSS private key for the chosen XMSS signature method.+      * New seeds for public/private key and pseudo random function input are+      * generated using the provided RNG. The appropriate WOTS signature method+      * will be automatically set based on the chosen XMSS signature method.+      *+      * @param xmss_algo_id Identifier for the selected XMSS signature method.+      * @param rng A random number generator to use for key generation.+      **/+      XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,+                      RandomNumberGenerator& rng); -#ifndef BOTAN_XMSS_H_-#define BOTAN_XMSS_H_+      /**+       * Creates an XMSS_PrivateKey from a byte sequence produced by+       * raw_private_key().+       *+       * @param raw_key An XMSS private key serialized using raw_private_key().+       **/+      XMSS_PrivateKey(const secure_vector<uint8_t>& raw_key); -#include <botan/xmss_publickey.h>-#include <botan/xmss_privatekey.h>+      /**+       * Creates a new XMSS private key for the chosen XMSS signature method+       * using precomputed seeds for public/private keys and pseudo random+       * function input. The appropriate WOTS signature method will be+       * automatically set, based on the chosen XMSS signature method.+       *+       * @param xmss_algo_id Identifier for the selected XMSS signature method.+       * @param idx_leaf Index of the next unused leaf.+       * @param wots_priv_seed A seed to generate a Winternitz-One-Time-+       *                      Signature private key from.+       * @param prf a secret n-byte key sourced from a secure source+       *        of uniformly random data.+       * @param root Root node of the binary hash tree.+       * @param public_seed The public seed.+       **/+      XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,+                      size_t idx_leaf,+                      const secure_vector<uint8_t>& wots_priv_seed,+                      const secure_vector<uint8_t>& prf,+                      const secure_vector<uint8_t>& root,+                      const secure_vector<uint8_t>& public_seed);++      bool stateful_operation() const override { return true; }++      /**+       * Retrieves the last unused leaf index of the private key. Reusing a leaf+       * by utilizing leaf indices lower than the last unused leaf index will+       * compromise security.+       *+       * @return Index of the last unused leaf.+       **/+      size_t unused_leaf_index() const;++      /**+       * Sets the last unused leaf index of the private key. The leaf index+       * will be updated automatically during every signing operation, and+       * should not be set manually.+       *+       * @param idx Index of the last unused leaf.+       **/+      void set_unused_leaf_index(size_t idx);++      size_t reserve_unused_leaf_index();++      /**+       * Winternitz One Time Signature Scheme key utilized for signing+       * operations.+       *+       * @return WOTS+ private key.+       **/+      const XMSS_WOTS_PrivateKey& wots_private_key() const+         {+         return m_wots_priv_key;+         }++      /**+       * Winternitz One Time Signature Scheme key utilized for signing+       * operations.+       *+       * @return WOTS+ private key.+       **/+      XMSS_WOTS_PrivateKey& wots_private_key()+         {+         return m_wots_priv_key;+         }++      const secure_vector<uint8_t>& prf() const+         {+         return m_prf;+         }++      secure_vector<uint8_t>& prf()+         {+         return m_prf;+         }++      void set_public_seed(+         const secure_vector<uint8_t>& public_seed) override+         {+         m_public_seed = public_seed;+         m_wots_priv_key.set_public_seed(public_seed);+         }++      void set_public_seed(secure_vector<uint8_t>&& public_seed) override+         {+         m_public_seed = std::move(public_seed);+         m_wots_priv_key.set_public_seed(m_public_seed);+         }++      const secure_vector<uint8_t>& public_seed() const override+         {+         return m_public_seed;+         }++      std::unique_ptr<PK_Ops::Signature>+      create_signature_op(RandomNumberGenerator&,+                          const std::string&,+                          const std::string& provider) const override;++      secure_vector<uint8_t> private_key_bits() const override;++      size_t size() const override+         {+         return XMSS_PublicKey::size() ++                sizeof(uint32_t) ++                2 * XMSS_PublicKey::m_xmss_params.element_size();+         }++      /**+       * Generates a non standartized byte sequence representing the XMSS+       * private key.+       *+       * @return byte sequence consisting of the following elements in order:+       *         4-byte OID, n-byte root node, n-byte public seed,+       *         8-byte unused leaf index, n-byte prf seed, n-byte private seed.+       **/+      secure_vector<uint8_t> raw_private_key() const;+      /**+       * Algorithm 9: "treeHash"+       * Computes the internal n-byte nodes of a Merkle tree.+       *+       * @param start_idx The start index.+       * @param target_node_height Height of the target node.+       * @param adrs Address of the tree containing the target node.+       *+       * @return The root node of a tree of height target_node height with the+       *         leftmost leaf being the hash of the WOTS+ pk with index+       *         start_idx.+       **/+      secure_vector<uint8_t> tree_hash(+         size_t start_idx,+         size_t target_node_height,+         XMSS_Address& adrs);++   private:+      /**+       * Fetches shared unused leaf index from the index registry+       **/+      std::shared_ptr<Atomic<size_t>> recover_global_leaf_index() const;++      inline void tree_hash_subtree(secure_vector<uint8_t>& result,+                                    size_t start_idx,+                                    size_t target_node_height,+                                    XMSS_Address& adrs)+         {+         return tree_hash_subtree(result, start_idx, target_node_height, adrs, m_hash);+         }+++      /**+       * Helper for multithreaded tree hashing.+       */+      void tree_hash_subtree(secure_vector<uint8_t>& result,+                             size_t start_idx,+                             size_t target_node_height,+                             XMSS_Address& adrs,+                             XMSS_Hash& hash);++      XMSS_WOTS_PrivateKey m_wots_priv_key;+      XMSS_Hash m_hash;+      secure_vector<uint8_t> m_prf;+      XMSS_Index_Registry& m_index_reg;+   };++}  #endif
third_party/botan/src/lib/pubkey/xmss/xmss_address.h view
@@ -8,7 +8,7 @@ #ifndef BOTAN_XMSS_ADDRESS_H_ #define BOTAN_XMSS_ADDRESS_H_ -#include <botan/xmss_tools.h>+#include <botan/types.h>  namespace Botan { 
third_party/botan/src/lib/pubkey/xmss/xmss_common_ops.cpp view
@@ -6,7 +6,7 @@  * Botan is released under the Simplified BSD License (see license.txt)  **/ -#include <botan/xmss_common_ops.h>+#include <botan/internal/xmss_common_ops.h>  namespace Botan { 
third_party/botan/src/lib/pubkey/xmss/xmss_common_ops.h view
@@ -11,7 +11,7 @@ #include <vector> #include <botan/secmem.h> #include <botan/xmss_parameters.h>-#include <botan/xmss_address.h>+#include <botan/internal/xmss_address.h> #include <botan/xmss_hash.h>  BOTAN_FUTURE_INTERNAL_HEADER(xmss_common_ops.h)@@ -42,6 +42,7 @@         * @param[in] seed The seed for G.         * @param[in] hash Instance of XMSS_Hash, that may only by the thead         *            executing generate_public_key.+        * @param[in] params         **/       static void randomize_tree_hash(          secure_vector<uint8_t>& result,@@ -67,6 +68,7 @@        * @param[in] seed The seed generated during the public key generation.        * @param[in] hash Instance of XMSS_Hash, that may only be used by the        *            thead executing create_l_tree.+       * @param[in] params       **/       static void create_l_tree(secure_vector<uint8_t>& result,                                 wots_keysig_t pk,
third_party/botan/src/lib/pubkey/xmss/xmss_index_registry.cpp view
@@ -7,7 +7,7 @@  * Botan is released under the Simplified BSD License (see license.txt)  **/ -#include <botan/xmss_index_registry.h>+#include <botan/internal/xmss_index_registry.h> #include <botan/hash.h> #include <limits> 
third_party/botan/src/lib/pubkey/xmss/xmss_index_registry.h view
@@ -11,7 +11,7 @@ #include <string>  #include <botan/secmem.h>-#include <botan/atomic.h>+#include <botan/internal/atomic.h> #include <botan/mutex.h>  //BOTAN_FUTURE_INTERNAL_HEADER(xmss_index_registry.h)
third_party/botan/src/lib/pubkey/xmss/xmss_key_pair.h view
@@ -8,10 +8,7 @@ #ifndef BOTAN_XMSS_KEY_PAIR_H_ #define BOTAN_XMSS_KEY_PAIR_H_ -#include <botan/xmss_parameters.h>-#include <botan/xmss_wots_parameters.h>-#include <botan/xmss_publickey.h>-#include <botan/xmss_privatekey.h>+#include <botan/xmss.h>  BOTAN_DEPRECATED_HEADER(xmss_key_pair.h) 
third_party/botan/src/lib/pubkey/xmss/xmss_parameters.h view
@@ -8,7 +8,7 @@ #ifndef BOTAN_XMSS_PARAMETERS_H_ #define BOTAN_XMSS_PARAMETERS_H_ -#include <botan/xmss_wots_parameters.h>+#include <botan/xmss_wots.h> #include <string>  namespace Botan {
third_party/botan/src/lib/pubkey/xmss/xmss_privatekey.cpp view
@@ -15,10 +15,13 @@  * Botan is released under the Simplified BSD License (see license.txt)  **/ -#include <botan/xmss_privatekey.h>+#include <botan/xmss.h> #include <botan/internal/xmss_signature_operation.h>-#include <botan/xmss_common_ops.h>+#include <botan/internal/xmss_index_registry.h>+#include <botan/internal/xmss_common_ops.h> #include <botan/ber_dec.h>+#include <botan/der_enc.h>+#include <iterator>  #if defined(BOTAN_HAS_THREAD_UTILS)    #include <botan/internal/thread_pool.h>@@ -112,6 +115,24 @@                       adrs));    } ++XMSS_PrivateKey::XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,+                                 size_t idx_leaf,+                                 const secure_vector<uint8_t>& wots_priv_seed,+                                 const secure_vector<uint8_t>& prf,+                                 const secure_vector<uint8_t>& root,+                                 const secure_vector<uint8_t>& public_seed)+   : XMSS_PublicKey(xmss_algo_id, root, public_seed),+     m_wots_priv_key(XMSS_PublicKey::m_xmss_params.ots_oid(),+                     public_seed,+                     wots_priv_seed),+     m_hash(XMSS_PublicKey::m_xmss_params.hash_function_name()),+     m_prf(prf),+     m_index_reg(XMSS_Index_Registry::get_instance())+   {+   set_unused_leaf_index(idx_leaf);+   }+ secure_vector<uint8_t> XMSS_PrivateKey::tree_hash(size_t start_idx,                            size_t target_node_height,@@ -295,16 +316,57 @@    result = nodes[level - 1];    } +secure_vector<uint8_t> XMSS_PrivateKey::private_key_bits() const+   {+   return DER_Encoder().encode(raw_private_key(), OCTET_STRING).get_contents();+   }+ std::shared_ptr<Atomic<size_t>> XMSS_PrivateKey::recover_global_leaf_index() const    {    BOTAN_ASSERT(m_wots_priv_key.private_seed().size() ==                 XMSS_PublicKey::m_xmss_params.element_size() &&                 m_prf.size() == XMSS_PublicKey::m_xmss_params.element_size(),-                "Trying to retrieve index for partially initialized "-                "key.");-   return m_index_reg.get(m_wots_priv_key.private_seed(),-                          m_prf);+                "Trying to retrieve index for partially initialized key");+   return m_index_reg.get(m_wots_priv_key.private_seed(), m_prf);+   }++void XMSS_PrivateKey::set_unused_leaf_index(size_t idx)+   {+   if(idx >= (1ull << XMSS_PublicKey::m_xmss_params.tree_height()))+      {+      throw Decoding_Error("XMSS private key leaf index out of bounds");+      }+   else+      {+      std::atomic<size_t>& index =+         static_cast<std::atomic<size_t>&>(*recover_global_leaf_index());+      size_t current = 0;++      do+         {+         current = index.load();+         if(current > idx)+            { return; }+         }+      while(!index.compare_exchange_strong(current, idx));+      }+   }++size_t XMSS_PrivateKey::reserve_unused_leaf_index()+   {+   size_t idx = (static_cast<std::atomic<size_t>&>(+                    *recover_global_leaf_index())).fetch_add(1);+   if(idx >= (1ull << XMSS_PublicKey::m_xmss_params.tree_height()))+      {+      throw Decoding_Error("XMSS private key, one time signatures exhaused");+      }+   return idx;+   }++size_t XMSS_PrivateKey::unused_leaf_index() const+   {+   return *recover_global_leaf_index();    }  secure_vector<uint8_t> XMSS_PrivateKey::raw_private_key() const
third_party/botan/src/lib/pubkey/xmss/xmss_privatekey.h view
@@ -1,5 +1,4 @@ /*- * XMSS_PrivateKey.h  * (C) 2016,2017,2018 Matthias Gierlings  *  * Botan is released under the Simplified BSD License (see license.txt)@@ -8,265 +7,7 @@ #ifndef BOTAN_XMSS_PRIVATEKEY_H_ #define BOTAN_XMSS_PRIVATEKEY_H_ -#include <cstddef>-#include <iterator>-#include <memory>-#include <botan/alg_id.h>-#include <botan/exceptn.h>-#include <botan/pk_keys.h>-#include <botan/types.h>-#include <botan/xmss_parameters.h>-#include <botan/xmss_publickey.h>-#include <botan/atomic.h>-#include <botan/xmss_wots_privatekey.h>-#include <botan/xmss_index_registry.h>--namespace Botan {--/**- * An XMSS: Extended Hash-Based Signature private key.- * The XMSS private key does not support the X509 and PKCS7 standard. Instead- * the raw format described in [1] is used.- *- * [1] XMSS: Extended Hash-Based Signatures,- *     Request for Comments: 8391- *     Release: May 2018.- *     https://datatracker.ietf.org/doc/rfc8391/- **/-class BOTAN_PUBLIC_API(2,0) XMSS_PrivateKey final : public virtual XMSS_PublicKey,-   public virtual Private_Key-   {-   public:-      /**-      * Creates a new XMSS private key for the chosen XMSS signature method.-      * New seeds for public/private key and pseudo random function input are-      * generated using the provided RNG. The appropriate WOTS signature method-      * will be automatically set based on the chosen XMSS signature method.-      *-      * @param xmss_algo_id Identifier for the selected XMSS signature method.-      * @param rng A random number generator to use for key generation.-      **/-      XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,-                      RandomNumberGenerator& rng);--      /**-       * Creates an XMSS_PrivateKey from a byte sequence produced by-       * raw_private_key().-       *-       * @param raw_key An XMSS private key serialized using raw_private_key().-       **/-      XMSS_PrivateKey(const secure_vector<uint8_t>& raw_key);--      /**-       * Creates a new XMSS private key for the chosen XMSS signature method-       * using precomputed seeds for public/private keys and pseudo random-       * function input. The appropriate WOTS signature method will be-       * automatically set, based on the chosen XMSS signature method.-       *-       * @param xmss_algo_id Identifier for the selected XMSS signature method.-       * @param idx_leaf Index of the next unused leaf.-       * @param wots_priv_seed A seed to generate a Winternitz-One-Time--       *                      Signature private key from.-       * @param prf a secret n-byte key sourced from a secure source-       *        of uniformly random data.-       * @param root Root node of the binary hash tree.-       * @param public_seed The public seed.-       **/-      XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,-                      size_t idx_leaf,-                      const secure_vector<uint8_t>& wots_priv_seed,-                      const secure_vector<uint8_t>& prf,-                      const secure_vector<uint8_t>& root,-                      const secure_vector<uint8_t>& public_seed)-         : XMSS_PublicKey(xmss_algo_id, root, public_seed),-           m_wots_priv_key(XMSS_PublicKey::m_xmss_params.ots_oid(),-                           public_seed,-                           wots_priv_seed),-           m_hash(XMSS_PublicKey::m_xmss_params.hash_function_name()),-           m_prf(prf),-           m_index_reg(XMSS_Index_Registry::get_instance())-         {-         set_unused_leaf_index(idx_leaf);-         }--      bool stateful_operation() const override { return true; }--      /**-       * Retrieves the last unused leaf index of the private key. Reusing a leaf-       * by utilizing leaf indices lower than the last unused leaf index will-       * compromise security.-       *-       * @return Index of the last unused leaf.-       **/-      size_t unused_leaf_index() const-         {-         return *recover_global_leaf_index();-         }--      /**-       * Sets the last unused leaf index of the private key. The leaf index-       * will be updated automatically during every signing operation, and-       * should not be set manually.-       *-       * @param idx Index of the last unused leaf.-       **/-      void set_unused_leaf_index(size_t idx)-         {-         if(idx >= (1ull << XMSS_PublicKey::m_xmss_params.tree_height()))-            {-            throw Decoding_Error("XMSS private key leaf index out of bounds");-            }-         else-            {-            std::atomic<size_t>& index =-               static_cast<std::atomic<size_t>&>(*recover_global_leaf_index());-            size_t current = 0;--            do-               {-               current = index.load();-               if(current > idx)-                  { return; }-               }-            while(!index.compare_exchange_strong(current, idx));-            }-         }--      size_t reserve_unused_leaf_index()-         {-         size_t idx = (static_cast<std::atomic<size_t>&>(-                          *recover_global_leaf_index())).fetch_add(1);-         if(idx >= (1ull << XMSS_PublicKey::m_xmss_params.tree_height()))-            {-            throw Decoding_Error("XMSS private key, one time signatures exhaused");-            }-         return idx;-         }--      /**-       * Winternitz One Time Signature Scheme key utilized for signing-       * operations.-       *-       * @return WOTS+ private key.-       **/-      const XMSS_WOTS_PrivateKey& wots_private_key() const-         {-         return m_wots_priv_key;-         }--      /**-       * Winternitz One Time Signature Scheme key utilized for signing-       * operations.-       *-       * @return WOTS+ private key.-       **/-      XMSS_WOTS_PrivateKey& wots_private_key()-         {-         return m_wots_priv_key;-         }--      const secure_vector<uint8_t>& prf() const-         {-         return m_prf;-         }--      secure_vector<uint8_t>& prf()-         {-         return m_prf;-         }--      void set_public_seed(-         const secure_vector<uint8_t>& public_seed) override-         {-         m_public_seed = public_seed;-         m_wots_priv_key.set_public_seed(public_seed);-         }--      void set_public_seed(secure_vector<uint8_t>&& public_seed) override-         {-         m_public_seed = std::move(public_seed);-         m_wots_priv_key.set_public_seed(m_public_seed);-         }--      const secure_vector<uint8_t>& public_seed() const override-         {-         return m_public_seed;-         }--      std::unique_ptr<PK_Ops::Signature>-      create_signature_op(RandomNumberGenerator&,-                          const std::string&,-                          const std::string& provider) const override;--      secure_vector<uint8_t> private_key_bits() const override-         {-         return DER_Encoder().encode(raw_private_key(), OCTET_STRING).get_contents();-         }--      size_t size() const override-         {-         return XMSS_PublicKey::size() +-                sizeof(uint32_t) +-                2 * XMSS_PublicKey::m_xmss_params.element_size();-         }--      /**-       * Generates a non standartized byte sequence representing the XMSS-       * private key.-       *-       * @return byte sequence consisting of the following elements in order:-       *         4-byte OID, n-byte root node, n-byte public seed,-       *         8-byte unused leaf index, n-byte prf seed, n-byte private seed.-       **/-      secure_vector<uint8_t> raw_private_key() const;-      /**-       * Algorithm 9: "treeHash"-       * Computes the internal n-byte nodes of a Merkle tree.-       *-       * @param start_idx The start index.-       * @param target_node_height Height of the target node.-       * @param adrs Address of the tree containing the target node.-       *-       * @return The root node of a tree of height target_node height with the-       *         leftmost leaf being the hash of the WOTS+ pk with index-       *         start_idx.-       **/-      secure_vector<uint8_t> tree_hash(-         size_t start_idx,-         size_t target_node_height,-         XMSS_Address& adrs);--   private:-      /**-       * Fetches shared unused leaf index from the index registry-       **/-      std::shared_ptr<Atomic<size_t>> recover_global_leaf_index() const;--      inline void tree_hash_subtree(secure_vector<uint8_t>& result,-                                    size_t start_idx,-                                    size_t target_node_height,-                                    XMSS_Address& adrs)-         {-         return tree_hash_subtree(result, start_idx, target_node_height, adrs, m_hash);-         }---      /**-       * Helper for multithreaded tree hashing.-       */-      void tree_hash_subtree(secure_vector<uint8_t>& result,-                             size_t start_idx,-                             size_t target_node_height,-                             XMSS_Address& adrs,-                             XMSS_Hash& hash);--      XMSS_WOTS_PrivateKey m_wots_priv_key;-      XMSS_Hash m_hash;-      secure_vector<uint8_t> m_prf;-      XMSS_Index_Registry& m_index_reg;-   };--}+#include <botan/xmss.h>+BOTAN_DEPRECATED_HEADER(xmss_privatekey.h)  #endif-
third_party/botan/src/lib/pubkey/xmss/xmss_publickey.cpp view
@@ -14,10 +14,11 @@  * Botan is released under the Simplified BSD License (see license.txt)  **/ +#include <botan/xmss.h> #include <botan/internal/xmss_verification_operation.h>-#include <botan/xmss_publickey.h> #include <botan/der_enc.h> #include <botan/ber_dec.h>+#include <iterator>  namespace Botan { @@ -40,6 +41,13 @@  } +XMSS_PublicKey::XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,+                               RandomNumberGenerator& rng)+   : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),+     m_root(m_xmss_params.element_size()),+     m_public_seed(rng.random_vec(m_xmss_params.element_size()))+   {}+ XMSS_PublicKey::XMSS_PublicKey(const std::vector<uint8_t>& key_bits)    : m_raw_key(extract_raw_key(key_bits)),      m_xmss_params(XMSS_PublicKey::deserialize_xmss_oid(m_raw_key)),@@ -109,6 +117,13 @@              std::back_inserter(result));     return result;+   }++std::vector<uint8_t> XMSS_PublicKey::public_key_bits() const+   {+   std::vector<uint8_t> output;+   DER_Encoder(output).encode(raw_public_key(), OCTET_STRING);+   return output;    }  }
third_party/botan/src/lib/pubkey/xmss/xmss_publickey.h view
@@ -1,7 +1,5 @@ /*- * XMSS Public Key- * (C) 2016,2017 Matthias Gierlings- * (C) 2019 René Korthaus, Rohde & Schwarz Cybersecurity+ * (C) 2016,2017,2018 Matthias Gierlings  *  * Botan is released under the Simplified BSD License (see license.txt)  **/@@ -9,266 +7,8 @@ #ifndef BOTAN_XMSS_PUBLICKEY_H_ #define BOTAN_XMSS_PUBLICKEY_H_ -#include <cstddef>-#include <iterator>-#include <memory>-#include <string>-#include <botan/alg_id.h>-#include <botan/asn1_oid.h>-#include <botan/der_enc.h>-#include <botan/exceptn.h>-#include <botan/rng.h>-#include <botan/types.h>-#include <botan/pk_keys.h>-#include <botan/xmss_parameters.h>-#include <botan/xmss_wots_parameters.h>-#include <botan/pk_ops.h>--namespace Botan {--class XMSS_Verification_Operation;--/**- * An XMSS: Extended Hash-Based Signature public key.- *- * [1] XMSS: Extended Hash-Based Signatures,- *     Request for Comments: 8391- *     Release: May 2018.- *     https://datatracker.ietf.org/doc/rfc8391/- **/-class BOTAN_PUBLIC_API(2,0) XMSS_PublicKey : public virtual Public_Key-   {-   public:-      /**-       * Creates a new XMSS public key for the chosen XMSS signature method.-       * New public and prf seeds are generated using rng. The appropriate WOTS-       * signature method will be automatically set based on the chosen XMSS-       * signature method.-       *-       * @param xmss_oid Identifier for the selected XMSS signature method.-       * @param rng A random number generator to use for key generation.-       **/-      XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,-                     RandomNumberGenerator& rng)-         : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),-           m_root(m_xmss_params.element_size()),-           m_public_seed(rng.random_vec(m_xmss_params.element_size())) {}--      /**-       * Loads a public key.-       *-       * Public key must be encoded as in RFC-       * draft-vangeest-x509-hash-sigs-03.-       *-       * @param key_bits DER encoded public key bits-       */-      XMSS_PublicKey(const std::vector<uint8_t>& key_bits);--      /**-       * Creates a new XMSS public key for a chosen XMSS signature method as-       * well as pre-computed root node and public_seed values.-       *-       * @param xmss_oid Identifier for the selected XMSS signature method.-       * @param root Root node value.-       * @param public_seed Public seed value.-       **/-      XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,-                     const secure_vector<uint8_t>& root,-                     const secure_vector<uint8_t>& public_seed)-         : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),-           m_root(root), m_public_seed(public_seed) {}--      /**-       * Creates a new XMSS public key for a chosen XMSS signature method as-       * well as pre-computed root node and public_seed values.-       *-       * @param xmss_oid Identifier for the selected XMSS signature method.-       * @param root Root node value.-       * @param public_seed Public seed value.-       **/-      XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,-                     secure_vector<uint8_t>&& root,-                     secure_vector<uint8_t>&& public_seed)-         : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),-           m_root(std::move(root)), m_public_seed(std::move(public_seed)) {}--      /**-       * Retrieves the chosen XMSS signature method.-       *-       * @return XMSS signature method identifier.-       **/-      XMSS_Parameters::xmss_algorithm_t xmss_oid() const-         {-         return m_xmss_params.oid();-         }--      /**-       * Sets the chosen XMSS signature method-       **/-      void set_xmss_oid(XMSS_Parameters::xmss_algorithm_t xmss_oid)-         {-         m_xmss_params = XMSS_Parameters(xmss_oid);-         m_wots_params = XMSS_WOTS_Parameters(m_xmss_params.ots_oid());-         }--      /**-       * Retrieves the XMSS parameters determined by the chosen XMSS Signature-       * method.-       *-       * @return XMSS parameters.-       **/-      const XMSS_Parameters& xmss_parameters() const-         {-         return m_xmss_params;-         }--      /**-       * Retrieves the XMSS parameters determined by the chosen XMSS Signature-       * method.-       *-       * @return XMSS parameters.-       **/-      std::string xmss_hash_function() const-         {-         return m_xmss_params.hash_function_name();-         }--      /**-       * Retrieves the Winternitz One Time Signature (WOTS) method,-       * corresponding to the chosen XMSS signature method.-       *-       * @return XMSS WOTS signature method identifier.-       **/-      XMSS_WOTS_Parameters::ots_algorithm_t wots_oid() const-         {-         return m_wots_params.oid();-         }--      /**-       * Retrieves the Winternitz One Time Signature (WOTS) parameters-       * corresponding to the chosen XMSS signature method.-       *-       * @return XMSS WOTS signature method parameters.-       **/-      const XMSS_WOTS_Parameters& wots_parameters() const-         {-         return m_wots_params;-         }--      secure_vector<uint8_t>& root()-         {-         return m_root;-         }--      void set_root(const secure_vector<uint8_t>& root)-         {-         m_root = root;-         }--      void set_root(secure_vector<uint8_t>&& root)-         {-         m_root = std::move(root);-         }--      const secure_vector<uint8_t>& root() const-         {-         return m_root;-         }--      virtual secure_vector<uint8_t>& public_seed()-         {-         return m_public_seed;-         }--      virtual void set_public_seed(const secure_vector<uint8_t>& public_seed)-         {-         m_public_seed = public_seed;-         }--      virtual void set_public_seed(secure_vector<uint8_t>&& public_seed)-         {-         m_public_seed = std::move(public_seed);-         }--      virtual const secure_vector<uint8_t>& public_seed() const-         {-         return m_public_seed;-         }--      std::string algo_name() const override-         {-         return "XMSS";-         }--      AlgorithmIdentifier algorithm_identifier() const override-         {-         return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_EMPTY_PARAM);-         }--      bool check_key(RandomNumberGenerator&, bool) const override-         {-         return true;-         }--      std::unique_ptr<PK_Ops::Verification>-      create_verification_op(const std::string&,-                             const std::string& provider) const override;--      size_t estimated_strength() const override-         {-         return m_xmss_params.estimated_strength();-         }--      size_t key_length() const override-         {-         return m_xmss_params.estimated_strength();-         }--      /**-       * Returns the encoded public key as defined in RFC-       * draft-vangeest-x509-hash-sigs-03.-       *-       * @return encoded public key bits-       **/-      std::vector<uint8_t> public_key_bits() const override-         {-         std::vector<uint8_t> output;-         DER_Encoder(output).encode(raw_public_key(), OCTET_STRING);-         return output;-         }--      /**-       * Size in bytes of the serialized XMSS public key produced by-       * raw_public_key().-       *-       * @return size in bytes of serialized Public Key.-       **/-      virtual size_t size() const-         {-         return sizeof(uint32_t) + 2 * m_xmss_params.element_size();-         }--      /**-       * Generates a byte sequence representing the XMSS-       * public key, as defined in [1] (p. 23, "XMSS Public Key")-       *-       * @return 4-byte OID, followed by n-byte root node, followed by-       *         public seed.-       **/-      virtual std::vector<uint8_t> raw_public_key() const;--   protected:-      std::vector<uint8_t> m_raw_key;-      XMSS_Parameters m_xmss_params;-      XMSS_WOTS_Parameters m_wots_params;-      secure_vector<uint8_t> m_root;-      secure_vector<uint8_t> m_public_seed;--   private:-      XMSS_Parameters::xmss_algorithm_t deserialize_xmss_oid(-         const std::vector<uint8_t>& raw_key);-   };--}+#include <botan/xmss.h>+BOTAN_DEPRECATED_HEADER(xmss_publickey.h)  #endif+
third_party/botan/src/lib/pubkey/xmss/xmss_signature.cpp view
@@ -6,6 +6,7 @@  **/  #include <botan/internal/xmss_signature.h>+#include <iterator>  namespace Botan { 
third_party/botan/src/lib/pubkey/xmss/xmss_signature.h view
@@ -13,7 +13,7 @@ #include <botan/types.h> #include <botan/secmem.h> #include <botan/xmss_parameters.h>-#include <botan/xmss_wots_publickey.h>+#include <botan/xmss_wots.h>  namespace Botan { 
third_party/botan/src/lib/pubkey/xmss/xmss_signature_operation.cpp view
@@ -14,6 +14,7 @@  **/  #include <botan/internal/xmss_signature_operation.h>+#include <botan/internal/xmss_tools.h>  namespace Botan { 
third_party/botan/src/lib/pubkey/xmss/xmss_signature_operation.h view
@@ -8,17 +8,11 @@ #ifndef BOTAN_XMSS_SIGNATURE_OPERATION_H_ #define BOTAN_XMSS_SIGNATURE_OPERATION_H_ -#include <cstddef>-#include <string>-#include <botan/secmem.h>-#include <botan/types.h>-#include <botan/xmss_parameters.h>-#include <botan/xmss_privatekey.h>-#include <botan/xmss_address.h> #include <botan/pk_ops.h>+#include <botan/xmss.h>+#include <botan/internal/xmss_address.h> #include <botan/internal/xmss_signature.h>-#include <botan/xmss_wots_publickey.h>-#include <botan/xmss_common_ops.h>+#include <botan/xmss_wots.h>  namespace Botan { 
third_party/botan/src/lib/pubkey/xmss/xmss_verification_operation.cpp view
@@ -9,7 +9,9 @@  **/  #include <botan/internal/xmss_verification_operation.h>-#include <botan/xmss_common_ops.h>+#include <botan/internal/xmss_common_ops.h>+#include <botan/internal/xmss_tools.h>+#include <array>  namespace Botan { 
third_party/botan/src/lib/pubkey/xmss/xmss_verification_operation.h view
@@ -8,13 +8,8 @@ #ifndef BOTAN_XMSS_VERIFICATION_OPERATION_H_ #define BOTAN_XMSS_VERIFICATION_OPERATION_H_ -#include <array>-#include <cstddef>-#include <iterator>-#include <string>-#include <botan/types.h>-#include <botan/xmss_publickey.h> #include <botan/pk_ops.h>+#include <botan/xmss.h> #include <botan/internal/xmss_signature.h>  namespace Botan {
+ third_party/botan/src/lib/pubkey/xmss/xmss_wots.h view
@@ -0,0 +1,752 @@+/*+ * XMSS WOTS+ * (C) 2016,2018 Matthias Gierlings+ *+ * Botan is released under the Simplified BSD License (see license.txt)+ **/++#ifndef BOTAN_XMSS_WOTS_H_+#define BOTAN_XMSS_WOTS_H_++#include <botan/asn1_obj.h>+#include <botan/exceptn.h>+#include <botan/pk_keys.h>+#include <botan/rng.h>+#include <botan/secmem.h>+#include <botan/xmss_hash.h>+#include <map>+#include <memory>+#include <string>+#include <vector>++namespace Botan {++/**+ * Descibes a signature method for XMSS Winternitz One Time Signatures,+ * as defined in:+ * [1] XMSS: Extended Hash-Based Signatures,+ *     Request for Comments: 8391+ *     Release: May 2018.+ *     https://datatracker.ietf.org/doc/rfc8391/+ **/+class XMSS_WOTS_Parameters final+   {+   public:+      enum ots_algorithm_t+         {+         WOTSP_SHA2_256 = 0x00000001,+         WOTSP_SHA2_512 = 0x00000002,+         WOTSP_SHAKE_256 = 0x00000003,+         WOTSP_SHAKE_512 = 0x00000004+         };++      XMSS_WOTS_Parameters(const std::string& algo_name);+      XMSS_WOTS_Parameters(ots_algorithm_t ots_spec);++      static ots_algorithm_t xmss_wots_id_from_string(const std::string& param_set);++      /**+       * Algorithm 1: convert input string to base.+       *+       * @param msg Input string (referred to as X in [1]).+       * @param out_size size of message in base w.+       *+       * @return Input string converted to the given base.+       **/+      secure_vector<uint8_t> base_w(const secure_vector<uint8_t>& msg, size_t out_size) const;++      secure_vector<uint8_t> base_w(size_t value) const;++      void append_checksum(secure_vector<uint8_t>& data);++      /**+       * @return XMSS WOTS registry name for the chosen parameter set.+       **/+      const std::string& name() const+         {+         return m_name;+         }++      /**+       * @return Botan name for the hash function used.+       **/+      const std::string& hash_function_name() const+         {+         return m_hash_name;+         }++      /**+       * Retrieves the uniform length of a message, and the size of+       * each node. This correlates to XMSS parameter "n" defined+       * in [1].+       *+       * @return element length in bytes.+       **/+      size_t element_size() const { return m_element_size; }++      /**+       * The Winternitz parameter.+       *+       * @return numeric base used for internal representation of+       *         data.+       **/+      size_t wots_parameter() const { return m_w; }++      size_t len() const { return m_len; }++      size_t len_1() const { return m_len_1; }++      size_t len_2() const { return m_len_2; }++      size_t lg_w() const { return m_lg_w; }++      ots_algorithm_t oid() const { return m_oid; }++      size_t estimated_strength() const { return m_strength; }++      bool operator==(const XMSS_WOTS_Parameters& p) const+         {+         return m_oid == p.m_oid;+         }++   private:+      static const std::map<std::string, ots_algorithm_t> m_oid_name_lut;+      ots_algorithm_t m_oid;+      std::string m_name;+      std::string m_hash_name;+      size_t m_element_size;+      size_t m_w;+      size_t m_len_1;+      size_t m_len_2;+      size_t m_len;+      size_t m_strength;+      uint8_t m_lg_w;+   };++class XMSS_Address;++typedef std::vector<secure_vector<uint8_t>> wots_keysig_t;++/**+ * A Winternitz One Time Signature public key for use with Extended Hash-Based+ * Signatures.+ **/+class XMSS_WOTS_PublicKey : virtual public Public_Key+   {+   public:+      class TreeSignature final+         {+         public:+            TreeSignature() = default;++            TreeSignature(const wots_keysig_t& ots_sig,+                          const wots_keysig_t& auth_path)+               : m_ots_sig(ots_sig), m_auth_path(auth_path)+               {}++            TreeSignature(wots_keysig_t&& ots_sig,+                          wots_keysig_t&& auth_path)+               : m_ots_sig(std::move(ots_sig)),+                 m_auth_path(std::move(auth_path))+               {}++            const wots_keysig_t& ots_signature() const+               {+               return m_ots_sig;+               }++            wots_keysig_t& ots_signature()+               {+               return m_ots_sig;+               }++            const wots_keysig_t& authentication_path() const+               {+               return m_auth_path;+               }++            wots_keysig_t& authentication_path()+               {+               return m_auth_path;+               }++         private:+            wots_keysig_t m_ots_sig;+            wots_keysig_t m_auth_path;+         };++      /**+       * Creates a XMSS_WOTS_PublicKey for the signature method identified by+       * oid. The public seed for this key will be initialized with a+       * uniformly random n-byte value, where "n" is the element size of the+       * selected signature method.+       *+       * @param oid Identifier for the selected signature method.+       **/+      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid)+         : m_wots_params(oid),+           m_hash(m_wots_params.hash_function_name()) {}++      /**+       * Creates a XMSS_WOTS_PublicKey for the signature method identified by+       * oid. The public seed for this key will be initialized with a+       * uniformly random n-byte value, where "n" is the element size of the+       * selected signature method.+       *+       * @param oid Identifier for the selected signature method.+       * @param rng A random number generate used to generate the public seed.+       **/+      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,+                          RandomNumberGenerator& rng)+         : m_wots_params(oid),+           m_hash(m_wots_params.hash_function_name()),+           m_public_seed(rng.random_vec(m_wots_params.element_size())) {}++      /**+       * Creates a XMSS_WOTS_PrivateKey for the signature method identified by+       * oid, with a precomputed public seed.+       *+       * @param oid Identifier for the selected signature method.+       * @param public_seed A precomputed public seed of n-bytes length.+       **/+      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,+                          secure_vector<uint8_t> public_seed)+         : m_wots_params(oid),+           m_hash(m_wots_params.hash_function_name()),+           m_public_seed(public_seed) {}++      /**+       * Creates a XMSS_WOTS_PublicKey for the signature method identified by+       * oid. The public seed will be initialized with a precomputed seed and+       * and precomputed key data which should be derived from a+       * XMSS_WOTS_PrivateKey.+       *+       * @param oid Ident:s/ifier for the selected signature methods.+       * @param public_seed A precomputed public seed of n-bytes length.+       * @param key Precomputed raw key data of the XMSS_WOTS_PublicKey.+       **/+      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,+                          secure_vector<uint8_t>&& public_seed,+                          wots_keysig_t&& key)+         : m_wots_params(oid),+           m_hash(m_wots_params.hash_function_name()),+           m_key(std::move(key)),+           m_public_seed(std::move(public_seed))+         {}++      /**+       * Creates a XMSS_WOTS_PublicKey for the signature method identified by+       * oid. The public seed will be initialized with a precomputed seed and+       * and precomputed key data which should be derived from a+       * XMSS_WOTS_PrivateKey.+       *+       * @param oid Identifier for the selected signature methods.+       * @param public_seed A precomputed public seed of n-bytes length.+       * @param key Precomputed raw key data of the XMSS_WOTS_PublicKey.+       **/+      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,+                          const secure_vector<uint8_t>& public_seed,+                          const wots_keysig_t& key)+         : m_wots_params(oid),+           m_hash(m_wots_params.hash_function_name()),+           m_key(key),+           m_public_seed(public_seed)+         {}++      /**+       * Creates a XMSS_WOTS_PublicKey form a message and signature using+       * Algorithm 6 WOTS_pkFromSig defined in the XMSS standard. This+       * overload is used to verify a message using a public key.+       *+       * @param oid WOTSP algorithm identifier.+       * @param msg A message.+       * @param sig A WOTS signature for msg.+       * @param adrs An XMSS_Address.+       * @param public_seed The public public_seed.+       **/+      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,+                          const secure_vector<uint8_t>& msg,+                          const wots_keysig_t& sig,+                          XMSS_Address& adrs,+                          const secure_vector<uint8_t>& public_seed)+         : m_wots_params(oid),+           m_hash(m_wots_params.hash_function_name()),+           m_key(pub_key_from_signature(msg,+                                        sig,+                                        adrs,+                                        public_seed)),+           m_public_seed(public_seed)+         {}++      /**+       * Retrieves the i-th element out of the length len chain of+       * n-byte elements contained in the public key.+       *+       * @param i index of the element.+       * @returns n-byte element addressed by i.+       **/+      const secure_vector<uint8_t>& operator[](size_t i) const { return m_key[i]; }+      secure_vector<uint8_t>& operator[](size_t i) { return m_key[i]; }++      /**+       * Convert the key into the raw key data. The key becomes a length+       * len vector of n-byte elements.+       **/+      operator const wots_keysig_t& () const { return m_key; }++      /**+       * Convert the key into the raw key data. The key becomes a length+       * len vector of n-byte elements.+       **/+      operator wots_keysig_t& () { return m_key; }++      const secure_vector<uint8_t>& public_seed() const { return m_public_seed; }++      secure_vector<uint8_t>& public_seed() { return m_public_seed; }++      void set_public_seed(const secure_vector<uint8_t>& public_seed)+         {+         m_public_seed = public_seed;+         }++      void set_public_seed(secure_vector<uint8_t>&& public_seed)+         {+         m_public_seed = std::move(public_seed);+         }++      const wots_keysig_t& key_data() const { return m_key; }++      wots_keysig_t& key_data() { return m_key; }++      void set_key_data(const wots_keysig_t& key_data)+         {+         m_key = key_data;+         }++      void set_key_data(wots_keysig_t&& key_data)+         {+         m_key = std::move(key_data);+         }++      const XMSS_WOTS_Parameters& wots_parameters() const+         {+         return m_wots_params;+         }++      std::string algo_name() const override+         {+         return m_wots_params.name();+         }++      AlgorithmIdentifier algorithm_identifier() const override+         {+         throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");+         }++      bool check_key(RandomNumberGenerator&, bool) const override+         {+         return true;+         }++      size_t estimated_strength() const override+         {+         return m_wots_params.estimated_strength();+         }++      size_t key_length() const override+         {+         return m_wots_params.estimated_strength();+         }++      std::vector<uint8_t> public_key_bits() const override+         {+         throw Not_Implemented("No key format defined for XMSS-WOTS");+         }++      bool operator==(const XMSS_WOTS_PublicKey& key)+         {+         return m_key == key.m_key;+         }++      bool operator!=(const XMSS_WOTS_PublicKey& key)+         {+         return !(*this == key);+         }++   protected:+      /**+       * Algorithm 2: Chaining Function.+       *+       * Takes an n-byte input string and transforms it into a the function+       * result iterating the cryptographic hash function "F" steps times on+       * the input x using the outputs of the PRNG "G".+       *+       * This overload is used in multithreaded scenarios, where it is+       * required to provide seperate instances of XMSS_Hash to each+       * thread.+       *+       * @param[out] x An n-byte input string, that will be transformed into+       *               the chaining function result.+       * @param start_idx The start index.+       * @param steps A number of steps.+       * @param adrs An OTS Hash Address.+       * @param public_seed A public seed.+       * @param hash Instance of XMSS_Hash, that may only by the thead+       *        executing chain.+       **/+      void chain(secure_vector<uint8_t>& x,+                 size_t start_idx,+                 size_t steps,+                 XMSS_Address& adrs,+                 const secure_vector<uint8_t>& public_seed,+                 XMSS_Hash& hash);++      /**+       * Algorithm 2: Chaining Function.+       *+       * Takes an n-byte input string and transforms it into a the function+       * result iterating the cryptographic hash function "F" steps times on+       * the input x using the outputs of the PRNG "G".+       *+       * @param[out] x An n-byte input string, that will be transformed into+       *               the chaining function result.+       * @param start_idx The start index.+       * @param steps A number of steps.+       * @param adrs An OTS Hash Address.+       * @param public_seed A public seed.+       **/+      inline void chain(secure_vector<uint8_t>& x,+                        size_t start_idx,+                        size_t steps,+                        XMSS_Address& adrs,+                        const secure_vector<uint8_t>& public_seed)+         {+         chain(x, start_idx, steps, adrs, public_seed, m_hash);+         }++      XMSS_WOTS_Parameters m_wots_params;+      XMSS_Hash m_hash;+      wots_keysig_t m_key;+      secure_vector<uint8_t> m_public_seed;++   private:+      /**+       * Algorithm 6: "WOTS_pkFromSig"+       * Computes a Winternitz One Time Signature+ public key from a message and+       * its signature.+       *+       * @param msg A message.+       * @param sig The signature for msg.+       * @param adrs An address.+       * @param public_seed A public_seed.+       *+       * @return Temporary WOTS+ public key.+       **/+      wots_keysig_t pub_key_from_signature(+         const secure_vector<uint8_t>& msg,+         const wots_keysig_t& sig,+         XMSS_Address& adrs,+         const secure_vector<uint8_t>& public_seed);+   };++/** A Winternitz One Time Signature private key for use with Extended Hash-Based+ * Signatures.+ **/+class XMSS_WOTS_PrivateKey final : public virtual XMSS_WOTS_PublicKey,+   public virtual Private_Key+   {+   public:+      /**+       * Creates a WOTS private key for the chosen XMSS WOTS signature method.+       * Members need to be initialized manually.+       *+       * @param oid Identifier for the selected signature method.+       **/+      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid)+         : XMSS_WOTS_PublicKey(oid)+         {}++      /**+       * Creates a WOTS private key for the chosen XMSS WOTS signature method.+       *+       * @param oid Identifier for the selected signature method.+       * @param rng A random number generator to use for key generation.+       **/+      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,+                           RandomNumberGenerator& rng)+         : XMSS_WOTS_PublicKey(oid, rng),+           m_private_seed(rng.random_vec(m_wots_params.element_size()))+         {+         set_key_data(generate(m_private_seed));+         }++      /**+       * Constructs a WOTS private key. Chains will be generated on demand+       * applying a hash function to a unique value generated from a secret+       * seed and a counter. The secret seed of length n, will be+       * automatically generated using AutoSeeded_RNG(). "n" equals+       * the element size of the chosen WOTS security parameter set.+       *+       * @param oid Identifier for the selected signature method.+       * @param public_seed A public seed used for the pseudo random generation+       *        of public keys derived from this private key.+       * @param rng A random number generator to use for key generation.+       **/+      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,+                           const secure_vector<uint8_t>& public_seed,+                           RandomNumberGenerator& rng)+         : XMSS_WOTS_PublicKey(oid, public_seed),+           m_private_seed(rng.random_vec(m_wots_params.element_size()))+         {+         set_key_data(generate(m_private_seed));+         }++      /**+       * Constructs a WOTS private key. Chains will be generated on demand+       * applying a hash function to a unique value generated from a secret+       * seed and a counter. The secret seed of length n, will be+       * automatically generated using AutoSeeded_RNG(). "n" equals+       * the element size of the chosen WOTS security parameter set.+       *+       * @param oid Identifier for the selected signature method.+       * @param public_seed A public seed used for the pseudo random generation+       *        of public keys derived from this private key.+       **/+      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,+                           const secure_vector<uint8_t>& public_seed)+         : XMSS_WOTS_PublicKey(oid, public_seed)+         {}++      /**+       * Constructs a WOTS private key. Chains will be generated on demand+       * applying a hash function to a unique value generated from the+       * secret seed and a counter.+       *+       * @param oid Identifier for the selected signature method.+       * @param public_seed A public seed used for the pseudo random generation+       *        of public keys derived from this private key.+       * @param private_seed A secret uniformly random n-byte value.+       **/+      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,+                           const secure_vector<uint8_t>& public_seed,+                           const secure_vector<uint8_t>& private_seed)+         : XMSS_WOTS_PublicKey(oid, public_seed),+           m_private_seed(private_seed)+         {+         set_key_data(generate(private_seed));+         }++      /**+       * Retrieves the i-th WOTS private key using pseudo random key+       * (re-)generation.+       *+       * This overload is used in multithreaded scenarios, where it is+       * required to provide seperate instances of XMSS_Hash to each+       * thread.+       *+       * @param i Index of the key to retrieve.+       * @param hash Instance of XMSS_Hash, that may only be used by the+       *        thead executing at.+       *+       * @return WOTS secret key.+       **/+      wots_keysig_t at(size_t i, XMSS_Hash& hash);++      /**+       * Retrieves the i-th WOTS private key using pseudo random key+       * (re-)generation.+       *+       * @param i Index of the key to retrieve.+       *+       * @return WOTS secret key.+       **/+      inline wots_keysig_t operator[](size_t i)+         {+         return this->at(i, m_hash);+         }++      /**+       * Retrieves the i-th WOTS private key using pseudo random key+       * (re-)generation.+       *+       * This overload is used in multithreaded scenarios, where it is+       * required to provide seperate instances of XMSS_Hash to each+       * thread.+       *+       * @param adrs The address of the key to retrieve.+       * @param hash Instance of XMSS_Hash, that may only be used by the+       *        thead executing at.+       *+       * @return WOTS secret key.+       **/+      wots_keysig_t at(const XMSS_Address& adrs, XMSS_Hash& hash);++      inline wots_keysig_t operator[](const XMSS_Address& adrs)+         {+         return this->at(adrs, m_hash);+         }++      wots_keysig_t generate_private_key(const secure_vector<uint8_t>& priv_seed);++      /**+       * Algorithm 4: "WOTS_genPK"+       * Generates a Winternitz One Time Signature+ (WOTS+) Public Key from a+       * given private key.+       *+       * @param adrs Hash function address encoding the address of the WOTS++       *             key pair within a greater structure.+       *+       * @return A XMSS_WOTS_PublicKey.+       **/+      XMSS_WOTS_PublicKey generate_public_key(XMSS_Address& adrs);++      /**+       * Algorithm 4: "WOTS_genPK"+       * Initializes a Winternitz One Time Signature+ (WOTS+) Public Key's+       * key_data() member, with data derived from in_key_data using the+       * WOTS chaining function.+       *+       * This overload is used in multithreaded scenarios, where it is+       * required to provide seperate instances of XMSS_Hash to each+       * thread.+       *+       * @param[out] pub_key Public key to initialize key_data() member on.+       * @param in_key_data Input key material from private key used for+       *        public key generation.+       * @param adrs Hash function address encoding the address of+       *        the WOTS+ key pair within a greater structure.+       * @param hash Instance of XMSS_Hash, that may only by the thead+       *        executing generate_public_key.+       **/+      void generate_public_key(XMSS_WOTS_PublicKey& pub_key,+                               wots_keysig_t&& in_key_data,+                               XMSS_Address& adrs,+                               XMSS_Hash& hash);+      /**+       * Algorithm 4: "WOTS_genPK"+       * Initializes a Winternitz One Time Signature+ (WOTS+) Public Key's+       * key_data() member, with data derived from in_key_data using the+       * WOTS chaining function.+       *+       * @param[out] pub_key Public key to initialize key_data() member on.+       * @param in_key_data Input key material from private key used for+       *        public key generation.+       * @param adrs Hash function address encoding the address of+       *        the WOTS+ key pair within a greater structure.+       **/+      inline void generate_public_key(XMSS_WOTS_PublicKey& pub_key,+                                      wots_keysig_t&& in_key_data,+                                      XMSS_Address& adrs)+         {+         generate_public_key(pub_key, std::forward<wots_keysig_t>(in_key_data), adrs, m_hash);+         }++      /**+       * Algorithm 5: "WOTS_sign"+       * Generates a signature from a private key and a message.+       *+       * @param msg A message to sign.+       * @param adrs An OTS hash address identifying the WOTS+ key pair+       *        used for signing.+       *+       * @return signature for msg.+       **/+      inline wots_keysig_t sign(const secure_vector<uint8_t>& msg,+                                XMSS_Address& adrs)+         {+         return sign(msg, adrs, m_hash);+         }++      /**+       * Algorithm 5: "WOTS_sign"+       * Generates a signature from a private key and a message.+       *+       * This overload is used in multithreaded scenarios, where it is+       * required to provide seperate instances of XMSS_Hash to each+       * thread.+       *+       * @param msg A message to sign.+       * @param adrs An OTS hash address identifying the WOTS+ key pair+       *        used for signing.+       * @param hash Instance of XMSS_Hash, that may only be used by the+       *        thead executing sign.+       *+       * @return signature for msg.+       **/+      wots_keysig_t sign(const secure_vector<uint8_t>& msg,+                         XMSS_Address& adrs,+                         XMSS_Hash& hash);++      /**+       * Retrieves the secret seed used to generate WOTS+ chains. The seed+       * should be a uniformly random n-byte value.+       *+       * @return secret seed.+       **/+      const secure_vector<uint8_t>& private_seed() const+         {+         return m_private_seed;+         }++      /**+       * Sets the secret seed used to generate WOTS+ chains. The seed+       * should be a uniformly random n-byte value.+       *+       * @param private_seed Uniformly random n-byte value.+       **/+      void set_private_seed(const secure_vector<uint8_t>& private_seed)+         {+         m_private_seed = private_seed;+         }++      /**+       * Sets the secret seed used to generate WOTS+ chains. The seed+       * should be a uniformly random n-byte value.+       *+       * @param private_seed Uniformly random n-byte value.+       **/+      void set_private_seed(secure_vector<uint8_t>&& private_seed)+         {+         m_private_seed = std::move(private_seed);+         }++      AlgorithmIdentifier+      pkcs8_algorithm_identifier() const override+         {+         throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");+         }++      secure_vector<uint8_t> private_key_bits() const override+         {+         throw Not_Implemented("No PKCS8 key format defined for XMSS-WOTS.");+         }++   private:+      /**+       * Algorithm 3: "Generating a WOTS+ Private Key".+       * Generates a private key.+       *+       * This overload is used in multithreaded scenarios, where it is+       * required to provide seperate instances of XMSS_Hash to each thread.+       *+       * @param private_seed Uniformly random n-byte value.+       * @param[in] hash Instance of XMSS_Hash, that may only be used by the+       *            thead executing generate.+       *+       * @returns a vector of length key_size() of vectors of n bytes length+       *          containing uniformly random data.+       **/+      wots_keysig_t generate(const secure_vector<uint8_t>& private_seed,+                             XMSS_Hash& hash);++      inline wots_keysig_t generate(const secure_vector<uint8_t>& private_seed)+         {+         return generate(private_seed, m_hash);+         }++      secure_vector<uint8_t> m_private_seed;+   };++}++#endif
third_party/botan/src/lib/pubkey/xmss/xmss_wots_addressed_privatekey.h view
@@ -8,9 +8,9 @@ #ifndef BOTAN_XMSS_WOTS_ADDRESSED_PRIVATEKEY_H_ #define BOTAN_XMSS_WOTS_ADDRESSED_PRIVATEKEY_H_ -#include <botan/xmss_address.h>+#include <botan/internal/xmss_address.h> #include <botan/internal/xmss_wots_addressed_publickey.h>-#include <botan/xmss_wots_privatekey.h>+#include <botan/xmss_wots.h>  namespace Botan { 
third_party/botan/src/lib/pubkey/xmss/xmss_wots_addressed_publickey.h view
@@ -9,8 +9,8 @@ #ifndef BOTAN_XMSS_WOTS_ADDRESSED_PUBLICKEY_H_ #define BOTAN_XMSS_WOTS_ADDRESSED_PUBLICKEY_H_ -#include <botan/xmss_address.h>-#include <botan/xmss_wots_publickey.h>+#include <botan/internal/xmss_address.h>+#include <botan/xmss_wots.h>  namespace Botan { 
third_party/botan/src/lib/pubkey/xmss/xmss_wots_parameters.cpp view
@@ -12,7 +12,8 @@  * Botan is released under the Simplified BSD License (see license.txt)  **/ -#include <botan/xmss_wots_parameters.h>+#include <botan/xmss_wots.h>+#include <botan/internal/xmss_tools.h> #include <botan/exceptn.h> #include <cmath> 
third_party/botan/src/lib/pubkey/xmss/xmss_wots_parameters.h view
@@ -8,115 +8,7 @@ #ifndef BOTAN_XMSS_WOTS_PARAMETERS_H_ #define BOTAN_XMSS_WOTS_PARAMETERS_H_ -#include <botan/xmss_tools.h>-#include <botan/secmem.h>-#include <map>-#include <string>--namespace Botan {--/**- * Descibes a signature method for XMSS Winternitz One Time Signatures,- * as defined in:- * [1] XMSS: Extended Hash-Based Signatures,- *     Request for Comments: 8391- *     Release: May 2018.- *     https://datatracker.ietf.org/doc/rfc8391/- **/-class XMSS_WOTS_Parameters final-   {-   public:-      enum ots_algorithm_t-         {-         WOTSP_SHA2_256 = 0x00000001,-         WOTSP_SHA2_512 = 0x00000002,-         WOTSP_SHAKE_256 = 0x00000003,-         WOTSP_SHAKE_512 = 0x00000004-         };--      XMSS_WOTS_Parameters(const std::string& algo_name);-      XMSS_WOTS_Parameters(ots_algorithm_t ots_spec);--      static ots_algorithm_t xmss_wots_id_from_string(const std::string& param_set);--      /**-       * Algorithm 1: convert input string to base.-       *-       * @param msg Input string (referred to as X in [1]).-       * @param out_size size of message in base w.-       *-       * @return Input string converted to the given base.-       **/-      secure_vector<uint8_t> base_w(const secure_vector<uint8_t>& msg, size_t out_size) const;--      secure_vector<uint8_t> base_w(size_t value) const;--      void append_checksum(secure_vector<uint8_t>& data);--      /**-       * @return XMSS WOTS registry name for the chosen parameter set.-       **/-      const std::string& name() const-         {-         return m_name;-         }--      /**-       * @return Botan name for the hash function used.-       **/-      const std::string& hash_function_name() const-         {-         return m_hash_name;-         }--      /**-       * Retrieves the uniform length of a message, and the size of-       * each node. This correlates to XMSS parameter "n" defined-       * in [1].-       *-       * @return element length in bytes.-       **/-      size_t element_size() const { return m_element_size; }--      /**-       * The Winternitz parameter.-       *-       * @return numeric base used for internal representation of-       *         data.-       **/-      size_t wots_parameter() const { return m_w; }--      size_t len() const { return m_len; }--      size_t len_1() const { return m_len_1; }--      size_t len_2() const { return m_len_2; }--      size_t lg_w() const { return m_lg_w; }--      ots_algorithm_t oid() const { return m_oid; }--      size_t estimated_strength() const { return m_strength; }--      bool operator==(const XMSS_WOTS_Parameters& p) const-         {-         return m_oid == p.m_oid;-         }--   private:-      static const std::map<std::string, ots_algorithm_t> m_oid_name_lut;-      ots_algorithm_t m_oid;-      std::string m_name;-      std::string m_hash_name;-      size_t m_element_size;-      size_t m_w;-      size_t m_len_1;-      size_t m_len_2;-      size_t m_len;-      size_t m_strength;-      uint8_t m_lg_w;-   };--}+#include <botan/xmss_wots.h>+BOTAN_DEPRECATED_HEADER(xmss_wots_parameters.h)  #endif
third_party/botan/src/lib/pubkey/xmss/xmss_wots_privatekey.cpp view
@@ -8,7 +8,9 @@  * Botan is released under the Simplified BSD License (see license.txt)  **/ -#include <botan/xmss_wots_privatekey.h>+#include <botan/xmss_wots.h>+#include <botan/internal/xmss_tools.h>+#include <botan/internal/xmss_address.h>  namespace Botan { @@ -77,6 +79,21 @@       }     return sig;+   }++wots_keysig_t XMSS_WOTS_PrivateKey::at(const XMSS_Address& adrs, XMSS_Hash& hash)+   {+   secure_vector<uint8_t> result;+   hash.prf(result, m_private_seed, adrs.bytes());+   return generate(result, hash);+   }++wots_keysig_t XMSS_WOTS_PrivateKey::at(size_t i, XMSS_Hash& hash)+   {+   secure_vector<uint8_t> idx_bytes;+   XMSS_Tools::concat(idx_bytes, i, m_wots_params.element_size());+   hash.h(idx_bytes, m_private_seed, idx_bytes);+   return generate(idx_bytes, hash);    }  }
third_party/botan/src/lib/pubkey/xmss/xmss_wots_privatekey.h view
@@ -8,328 +8,8 @@ #ifndef BOTAN_XMSS_WOTS_PRIVATEKEY_H_ #define BOTAN_XMSS_WOTS_PRIVATEKEY_H_ -#include <cstddef>-#include <memory>-#include <botan/alg_id.h>-#include <botan/exceptn.h>-#include <botan/pk_keys.h>-#include <botan/rng.h>-#include <botan/xmss_wots_parameters.h>-#include <botan/xmss_address.h>-#include <botan/xmss_wots_publickey.h>--namespace Botan {--/** A Winternitz One Time Signature private key for use with Extended Hash-Based- * Signatures.- **/-class XMSS_WOTS_PrivateKey final : public virtual XMSS_WOTS_PublicKey,-   public virtual Private_Key-   {-   public:-      /**-       * Creates a WOTS private key for the chosen XMSS WOTS signature method.-       * Members need to be initialized manually.-       *-       * @param oid Identifier for the selected signature method.-       **/-      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid)-         : XMSS_WOTS_PublicKey(oid)-         {}--      /**-       * Creates a WOTS private key for the chosen XMSS WOTS signature method.-       *-       * @param oid Identifier for the selected signature method.-       * @param rng A random number generator to use for key generation.-       **/-      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,-                           RandomNumberGenerator& rng)-         : XMSS_WOTS_PublicKey(oid, rng),-           m_private_seed(rng.random_vec(m_wots_params.element_size()))-         {-         set_key_data(generate(m_private_seed));-         }--      /**-       * Constructs a WOTS private key. Chains will be generated on demand-       * applying a hash function to a unique value generated from a secret-       * seed and a counter. The secret seed of length n, will be-       * automatically generated using AutoSeeded_RNG(). "n" equals-       * the element size of the chosen WOTS security parameter set.-       *-       * @param oid Identifier for the selected signature method.-       * @param public_seed A public seed used for the pseudo random generation-       *        of public keys derived from this private key.-       * @param rng A random number generator to use for key generation.-       **/-      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,-                           const secure_vector<uint8_t>& public_seed,-                           RandomNumberGenerator& rng)-         : XMSS_WOTS_PublicKey(oid, public_seed),-           m_private_seed(rng.random_vec(m_wots_params.element_size()))-         {-         set_key_data(generate(m_private_seed));-         }--      /**-       * Constructs a WOTS private key. Chains will be generated on demand-       * applying a hash function to a unique value generated from a secret-       * seed and a counter. The secret seed of length n, will be-       * automatically generated using AutoSeeded_RNG(). "n" equals-       * the element size of the chosen WOTS security parameter set.-       *-       * @param oid Identifier for the selected signature method.-       * @param public_seed A public seed used for the pseudo random generation-       *        of public keys derived from this private key.-       **/-      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,-                           const secure_vector<uint8_t>& public_seed)-         : XMSS_WOTS_PublicKey(oid, public_seed)-         {}--      /**-       * Constructs a WOTS private key. Chains will be generated on demand-       * applying a hash function to a unique value generated from the-       * secret seed and a counter.-       *-       * @param oid Identifier for the selected signature method.-       * @param public_seed A public seed used for the pseudo random generation-       *        of public keys derived from this private key.-       * @param private_seed A secret uniformly random n-byte value.-       **/-      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,-                           const secure_vector<uint8_t>& public_seed,-                           const secure_vector<uint8_t>& private_seed)-         : XMSS_WOTS_PublicKey(oid, public_seed),-           m_private_seed(private_seed)-         {-         set_key_data(generate(private_seed));-         }--      /**-       * Retrieves the i-th WOTS private key using pseudo random key-       * (re-)generation.-       *-       * This overload is used in multithreaded scenarios, where it is-       * required to provide seperate instances of XMSS_Hash to each-       * thread.-       *-       * @param i Index of the key to retrieve.-       * @param hash Instance of XMSS_Hash, that may only be used by the-       *        thead executing at.-       *-       * @return WOTS secret key.-       **/-      wots_keysig_t at(size_t i, XMSS_Hash& hash)-         {-         secure_vector<uint8_t> idx_bytes;-         XMSS_Tools::concat(idx_bytes, i, m_wots_params.element_size());-         hash.h(idx_bytes, m_private_seed, idx_bytes);-         return generate(idx_bytes, hash);-         }--      /**-       * Retrieves the i-th WOTS private key using pseudo random key-       * (re-)generation.-       *-       * @param i Index of the key to retrieve.-       *-       * @return WOTS secret key.-       **/-      inline wots_keysig_t operator[](size_t i)-         {-         return this->at(i, m_hash);-         }--      /**-       * Retrieves the i-th WOTS private key using pseudo random key-       * (re-)generation.-       *-       * This overload is used in multithreaded scenarios, where it is-       * required to provide seperate instances of XMSS_Hash to each-       * thread.-       *-       * @param adrs The address of the key to retrieve.-       * @param hash Instance of XMSS_Hash, that may only be used by the-       *        thead executing at.-       *-       * @return WOTS secret key.-       **/-      wots_keysig_t at(const XMSS_Address& adrs, XMSS_Hash& hash)-         {-         secure_vector<uint8_t> result;-         hash.prf(result, m_private_seed, adrs.bytes());-         return generate(result, hash);-         }--      inline wots_keysig_t operator[](const XMSS_Address& adrs)-         {-         return this->at(adrs, m_hash);-         }--      wots_keysig_t generate_private_key(const secure_vector<uint8_t>& priv_seed);--      /**-       * Algorithm 4: "WOTS_genPK"-       * Generates a Winternitz One Time Signature+ (WOTS+) Public Key from a-       * given private key.-       *-       * @param adrs Hash function address encoding the address of the WOTS+-       *             key pair within a greater structure.-       *-       * @return A XMSS_WOTS_PublicKey.-       **/-      XMSS_WOTS_PublicKey generate_public_key(XMSS_Address& adrs);--      /**-       * Algorithm 4: "WOTS_genPK"-       * Initializes a Winternitz One Time Signature+ (WOTS+) Public Key's-       * key_data() member, with data derived from in_key_data using the-       * WOTS chaining function.-       *-       * This overload is used in multithreaded scenarios, where it is-       * required to provide seperate instances of XMSS_Hash to each-       * thread.-       *-       * @param[out] pub_key Public key to initialize key_data() member on.-       * @param in_key_data Input key material from private key used for-       *        public key generation.-       * @param adrs Hash function address encoding the address of-       *        the WOTS+ key pair within a greater structure.-       * @param hash Instance of XMSS_Hash, that may only by the thead-       *        executing generate_public_key.-       **/-      void generate_public_key(XMSS_WOTS_PublicKey& pub_key,-                               wots_keysig_t&& in_key_data,-                               XMSS_Address& adrs,-                               XMSS_Hash& hash);-      /**-       * Algorithm 4: "WOTS_genPK"-       * Initializes a Winternitz One Time Signature+ (WOTS+) Public Key's-       * key_data() member, with data derived from in_key_data using the-       * WOTS chaining function.-       *-       * @param[out] pub_key Public key to initialize key_data() member on.-       * @param in_key_data Input key material from private key used for-       *        public key generation.-       * @param adrs Hash function address encoding the address of-       *        the WOTS+ key pair within a greater structure.-       **/-      inline void generate_public_key(XMSS_WOTS_PublicKey& pub_key,-                                      wots_keysig_t&& in_key_data,-                                      XMSS_Address& adrs)-         {-         generate_public_key(pub_key, std::forward<wots_keysig_t>(in_key_data), adrs, m_hash);-         }--      /**-       * Algorithm 5: "WOTS_sign"-       * Generates a signature from a private key and a message.-       *-       * @param msg A message to sign.-       * @param adrs An OTS hash address identifying the WOTS+ key pair-       *        used for signing.-       *-       * @return signature for msg.-       **/-      inline wots_keysig_t sign(const secure_vector<uint8_t>& msg,-                                XMSS_Address& adrs)-         {-         return sign(msg, adrs, m_hash);-         }--      /**-       * Algorithm 5: "WOTS_sign"-       * Generates a signature from a private key and a message.-       *-       * This overload is used in multithreaded scenarios, where it is-       * required to provide seperate instances of XMSS_Hash to each-       * thread.-       *-       * @param msg A message to sign.-       * @param adrs An OTS hash address identifying the WOTS+ key pair-       *        used for signing.-       * @param hash Instance of XMSS_Hash, that may only be used by the-       *        thead executing sign.-       *-       * @return signature for msg.-       **/-      wots_keysig_t sign(const secure_vector<uint8_t>& msg,-                         XMSS_Address& adrs,-                         XMSS_Hash& hash);--      /**-       * Retrieves the secret seed used to generate WOTS+ chains. The seed-       * should be a uniformly random n-byte value.-       *-       * @return secret seed.-       **/-      const secure_vector<uint8_t>& private_seed() const-         {-         return m_private_seed;-         }--      /**-       * Sets the secret seed used to generate WOTS+ chains. The seed-       * should be a uniformly random n-byte value.-       *-       * @param private_seed Uniformly random n-byte value.-       **/-      void set_private_seed(const secure_vector<uint8_t>& private_seed)-         {-         m_private_seed = private_seed;-         }--      /**-       * Sets the secret seed used to generate WOTS+ chains. The seed-       * should be a uniformly random n-byte value.-       *-       * @param private_seed Uniformly random n-byte value.-       **/-      void set_private_seed(secure_vector<uint8_t>&& private_seed)-         {-         m_private_seed = std::move(private_seed);-         }--      AlgorithmIdentifier-      pkcs8_algorithm_identifier() const override-         {-         throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");-         }--      secure_vector<uint8_t> private_key_bits() const override-         {-         throw Not_Implemented("No PKCS8 key format defined for XMSS-WOTS.");-         }--   private:-      /**-       * Algorithm 3: "Generating a WOTS+ Private Key".-       * Generates a private key.-       *-       * This overload is used in multithreaded scenarios, where it is-       * required to provide seperate instances of XMSS_Hash to each thread.-       *-       * @param private_seed Uniformly random n-byte value.-       * @param[in] hash Instance of XMSS_Hash, that may only be used by the-       *            thead executing generate.-       *-       * @returns a vector of length key_size() of vectors of n bytes length-       *          containing uniformly random data.-       **/-      wots_keysig_t generate(const secure_vector<uint8_t>& private_seed,-                             XMSS_Hash& hash);--      inline wots_keysig_t generate(const secure_vector<uint8_t>& private_seed)-         {-         return generate(private_seed, m_hash);-         }--      secure_vector<uint8_t> m_private_seed;-   };--}+#include <botan/xmss.h>+BOTAN_DEPRECATED_HEADER(xmss_wots_privatekey.h)  #endif 
third_party/botan/src/lib/pubkey/xmss/xmss_wots_publickey.cpp view
@@ -8,7 +8,8 @@  * Botan is released under the Simplified BSD License (see license.txt)  **/ -#include <botan/xmss_wots_publickey.h>+#include <botan/xmss_wots.h>+#include <botan/internal/xmss_address.h>  namespace Botan { 
third_party/botan/src/lib/pubkey/xmss/xmss_wots_publickey.h view
@@ -8,345 +8,7 @@ #ifndef BOTAN_XMSS_WOTS_PUBLICKEY_H_ #define BOTAN_XMSS_WOTS_PUBLICKEY_H_ -#include <cstddef>-#include <string>-#include <vector>-#include <botan/alg_id.h>-#include <botan/rng.h>-#include <botan/asn1_oid.h>-#include <botan/exceptn.h>-#include <botan/pk_keys.h>-#include <botan/types.h>-#include <botan/xmss_wots_parameters.h>-#include <botan/xmss_address.h>-#include <botan/xmss_hash.h>--namespace Botan {--typedef std::vector<secure_vector<uint8_t>> wots_keysig_t;--/**- * A Winternitz One Time Signature public key for use with Extended Hash-Based- * Signatures.- **/-class XMSS_WOTS_PublicKey : virtual public Public_Key-   {-   public:-      class TreeSignature final-         {-         public:-            TreeSignature() = default;--            TreeSignature(const wots_keysig_t& ots_sig,-                          const wots_keysig_t& auth_path)-               : m_ots_sig(ots_sig), m_auth_path(auth_path)-               {}--            TreeSignature(wots_keysig_t&& ots_sig,-                          wots_keysig_t&& auth_path)-               : m_ots_sig(std::move(ots_sig)),-                 m_auth_path(std::move(auth_path))-               {}--            const wots_keysig_t& ots_signature() const-               {-               return m_ots_sig;-               }--            wots_keysig_t& ots_signature()-               {-               return m_ots_sig;-               }--            const wots_keysig_t& authentication_path() const-               {-               return m_auth_path;-               }--            wots_keysig_t& authentication_path()-               {-               return m_auth_path;-               }--         private:-            wots_keysig_t m_ots_sig;-            wots_keysig_t m_auth_path;-         };--      /**-       * Creates a XMSS_WOTS_PublicKey for the signature method identified by-       * oid. The public seed for this key will be initialized with a-       * uniformly random n-byte value, where "n" is the element size of the-       * selected signature method.-       *-       * @param oid Identifier for the selected signature method.-       **/-      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid)-         : m_wots_params(oid),-           m_hash(m_wots_params.hash_function_name()) {}--      /**-       * Creates a XMSS_WOTS_PublicKey for the signature method identified by-       * oid. The public seed for this key will be initialized with a-       * uniformly random n-byte value, where "n" is the element size of the-       * selected signature method.-       *-       * @param oid Identifier for the selected signature method.-       * @param rng A random number generate used to generate the public seed.-       **/-      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,-                          RandomNumberGenerator& rng)-         : m_wots_params(oid),-           m_hash(m_wots_params.hash_function_name()),-           m_public_seed(rng.random_vec(m_wots_params.element_size())) {}--      /**-       * Creates a XMSS_WOTS_PrivateKey for the signature method identified by-       * oid, with a precomputed public seed.-       *-       * @param oid Identifier for the selected signature method.-       * @param public_seed A precomputed public seed of n-bytes length.-       **/-      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,-                          secure_vector<uint8_t> public_seed)-         : m_wots_params(oid),-           m_hash(m_wots_params.hash_function_name()),-           m_public_seed(public_seed) {}--      /**-       * Creates a XMSS_WOTS_PublicKey for the signature method identified by-       * oid. The public seed will be initialized with a precomputed seed and-       * and precomputed key data which should be derived from a-       * XMSS_WOTS_PrivateKey.-       *-       * @param oid Ident:s/ifier for the selected signature methods.-       * @param public_seed A precomputed public seed of n-bytes length.-       * @param key Precomputed raw key data of the XMSS_WOTS_PublicKey.-       **/-      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,-                          secure_vector<uint8_t>&& public_seed,-                          wots_keysig_t&& key)-         : m_wots_params(oid),-           m_hash(m_wots_params.hash_function_name()),-           m_key(std::move(key)),-           m_public_seed(std::move(public_seed))-         {}--      /**-       * Creates a XMSS_WOTS_PublicKey for the signature method identified by-       * oid. The public seed will be initialized with a precomputed seed and-       * and precomputed key data which should be derived from a-       * XMSS_WOTS_PrivateKey.-       *-       * @param oid Identifier for the selected signature methods.-       * @param public_seed A precomputed public seed of n-bytes length.-       * @param key Precomputed raw key data of the XMSS_WOTS_PublicKey.-       **/-      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,-                          const secure_vector<uint8_t>& public_seed,-                          const wots_keysig_t& key)-         : m_wots_params(oid),-           m_hash(m_wots_params.hash_function_name()),-           m_key(key),-           m_public_seed(public_seed)-         {}--      /**-       * Creates a XMSS_WOTS_PublicKey form a message and signature using-       * Algorithm 6 WOTS_pkFromSig defined in the XMSS standard. This-       * overload is used to verify a message using a public key.-       *-       * @param oid WOTSP algorithm identifier.-       * @param msg A message.-       * @param sig A WOTS signature for msg.-       * @param adrs An XMSS_Address.-       * @param public_seed The public public_seed.-       **/-      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,-                          const secure_vector<uint8_t>& msg,-                          const wots_keysig_t& sig,-                          XMSS_Address& adrs,-                          const secure_vector<uint8_t>& public_seed)-         : m_wots_params(oid),-           m_hash(m_wots_params.hash_function_name()),-           m_key(pub_key_from_signature(msg,-                                        sig,-                                        adrs,-                                        public_seed)),-           m_public_seed(public_seed)-         {}--      /**-       * Retrieves the i-th element out of the length len chain of-       * n-byte elements contained in the public key.-       *-       * @param i index of the element.-       * @returns n-byte element addressed by i.-       **/-      const secure_vector<uint8_t>& operator[](size_t i) const { return m_key[i]; }-      secure_vector<uint8_t>& operator[](size_t i) { return m_key[i]; }--      /**-       * Convert the key into the raw key data. The key becomes a length-       * len vector of n-byte elements.-       **/-      operator const wots_keysig_t& () const { return m_key; }--      /**-       * Convert the key into the raw key data. The key becomes a length-       * len vector of n-byte elements.-       **/-      operator wots_keysig_t& () { return m_key; }--      const secure_vector<uint8_t>& public_seed() const { return m_public_seed; }--      secure_vector<uint8_t>& public_seed() { return m_public_seed; }--      void set_public_seed(const secure_vector<uint8_t>& public_seed)-         {-         m_public_seed = public_seed;-         }--      void set_public_seed(secure_vector<uint8_t>&& public_seed)-         {-         m_public_seed = std::move(public_seed);-         }--      const wots_keysig_t& key_data() const { return m_key; }--      wots_keysig_t& key_data() { return m_key; }--      void set_key_data(const wots_keysig_t& key_data)-         {-         m_key = key_data;-         }--      void set_key_data(wots_keysig_t&& key_data)-         {-         m_key = std::move(key_data);-         }--      const XMSS_WOTS_Parameters& wots_parameters() const-         {-         return m_wots_params;-         }--      std::string algo_name() const override-         {-         return m_wots_params.name();-         }--      AlgorithmIdentifier algorithm_identifier() const override-         {-         throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");-         }--      bool check_key(RandomNumberGenerator&, bool) const override-         {-         return true;-         }--      size_t estimated_strength() const override-         {-         return m_wots_params.estimated_strength();-         }--      size_t key_length() const override-         {-         return m_wots_params.estimated_strength();-         }--      std::vector<uint8_t> public_key_bits() const override-         {-         throw Not_Implemented("No key format defined for XMSS-WOTS");-         }--      bool operator==(const XMSS_WOTS_PublicKey& key)-         {-         return m_key == key.m_key;-         }--      bool operator!=(const XMSS_WOTS_PublicKey& key)-         {-         return !(*this == key);-         }--   protected:-      /**-       * Algorithm 2: Chaining Function.-       *-       * Takes an n-byte input string and transforms it into a the function-       * result iterating the cryptographic hash function "F" steps times on-       * the input x using the outputs of the PRNG "G".-       *-       * This overload is used in multithreaded scenarios, where it is-       * required to provide seperate instances of XMSS_Hash to each-       * thread.-       *-       * @param[out] x An n-byte input string, that will be transformed into-       *               the chaining function result.-       * @param start_idx The start index.-       * @param steps A number of steps.-       * @param adrs An OTS Hash Address.-       * @param public_seed A public seed.-       * @param hash Instance of XMSS_Hash, that may only by the thead-       *        executing chain.-       **/-      void chain(secure_vector<uint8_t>& x,-                 size_t start_idx,-                 size_t steps,-                 XMSS_Address& adrs,-                 const secure_vector<uint8_t>& public_seed,-                 XMSS_Hash& hash);--      /**-       * Algorithm 2: Chaining Function.-       *-       * Takes an n-byte input string and transforms it into a the function-       * result iterating the cryptographic hash function "F" steps times on-       * the input x using the outputs of the PRNG "G".-       *-       * @param[out] x An n-byte input string, that will be transformed into-       *               the chaining function result.-       * @param start_idx The start index.-       * @param steps A number of steps.-       * @param adrs An OTS Hash Address.-       * @param public_seed A public seed.-       **/-      inline void chain(secure_vector<uint8_t>& x,-                        size_t start_idx,-                        size_t steps,-                        XMSS_Address& adrs,-                        const secure_vector<uint8_t>& public_seed)-         {-         chain(x, start_idx, steps, adrs, public_seed, m_hash);-         }--      XMSS_WOTS_Parameters m_wots_params;-      XMSS_Hash m_hash;-      wots_keysig_t m_key;-      secure_vector<uint8_t> m_public_seed;--   private:-      /**-       * Algorithm 6: "WOTS_pkFromSig"-       * Computes a Winternitz One Time Signature+ public key from a message and-       * its signature.-       *-       * @param msg A message.-       * @param sig The signature for msg.-       * @param adrs An address.-       * @param public_seed A public_seed.-       *-       * @return Temporary WOTS+ public key.-       **/-      wots_keysig_t pub_key_from_signature(-         const secure_vector<uint8_t>& msg,-         const wots_keysig_t& sig,-         XMSS_Address& adrs,-         const secure_vector<uint8_t>& public_seed);-   };--}+#include <botan/xmss.h>+BOTAN_DEPRECATED_HEADER(xmss_wots_publickey.h)  #endif
third_party/botan/src/lib/rng/processor_rng/info.txt view
@@ -14,3 +14,7 @@ x86_64 ppc64 </arch>++<isa>+ppc64:power9+</isa>
third_party/botan/src/lib/rng/rng.h view
@@ -68,7 +68,7 @@       */       template<typename T> void add_entropy_T(const T& t)          {-         static_assert(std::is_pod<T>::value, "add_entropy_T data must be POD");+         static_assert(std::is_standard_layout<T>::value && std::is_trivial<T>::value, "add_entropy_T data must be POD");          this->add_entropy(reinterpret_cast<const uint8_t*>(&t), sizeof(T));          } 
third_party/botan/src/lib/tls/asio/asio_stream.h view
@@ -334,28 +334,36 @@     private:       /**-       * @brief Internal wrapper type to adapt the expected signature of `async_shutdown`-       *        to the completion handler signature of `AsyncWriteOperation`.-       *-       * This is boilerplate to ignore the `size_t` parameter that is passed to the-       * completion handler of `AsyncWriteOperation`.-       *-       * @todo in C++14 and above this could be implemented as a mutable lambda expression-       *       that captures `handler` by perfect forwarding, like so:+       * @brief Internal wrapper type to adapt the expected signature of `async_shutdown` to the completion handler+       *        signature of `AsyncWriteOperation`.        *-       *       [h = std::forward<Handler>(handler)] (...) mutable { return h(ec); }+       * This is boilerplate to ignore the `size_t` parameter that is passed to the completion handler of+       * `AsyncWriteOperation`. Note that it needs to retain the wrapped handler's executor.        */-      template <typename Handler>-      class Wrapper+      template <typename Handler, typename Executor>+      struct Wrapper          {-         public:-            Wrapper(Handler&& handler) : _handler(std::forward<Handler>(handler)) {}-            void operator()(boost::system::error_code ec, size_t)-               {-               _handler(ec);-               }-         private:-            Handler _handler;+         void operator()(boost::system::error_code ec, std::size_t)+            {+            handler(ec);+            }++         using executor_type = boost::asio::associated_executor_t<Handler, Executor>;++         executor_type get_executor() const noexcept+            {+            return boost::asio::get_associated_executor(handler, io_executor);+            }++         using allocator_type = boost::asio::associated_allocator_t<Handler>;++         allocator_type get_allocator() const noexcept+            {+            return boost::asio::get_associated_allocator(handler);+            }++         Handler handler;+         Executor io_executor;          };     public:@@ -380,9 +388,9 @@          // If ec is set by native_handle->close(), the AsyncWriteOperation created below will do nothing but call the          // handler with the error_code set appropriately - no need to early return here. -         using ShutdownHandlerWrapper = Wrapper<ShutdownHandler>;+         using ShutdownHandlerWrapper = Wrapper<ShutdownHandler, typename Stream::executor_type>; -         ShutdownHandlerWrapper w(std::forward<ShutdownHandler>(handler));+         ShutdownHandlerWrapper w{std::forward<ShutdownHandler>(handler), get_executor()};          BOOST_ASIO_SHUTDOWN_HANDLER_CHECK(ShutdownHandler, w) type_check;           boost::asio::async_completion<ShutdownHandlerWrapper, void(boost::system::error_code, std::size_t)>
third_party/botan/src/lib/tls/credentials_manager.cpp view
@@ -6,6 +6,7 @@ */  #include <botan/credentials_manager.h>+#include <botan/pkix_types.h>  namespace Botan { 
third_party/botan/src/lib/tls/tls_extensions.h view
@@ -14,7 +14,7 @@ #include <botan/tls_magic.h> #include <botan/tls_version.h> #include <botan/secmem.h>-#include <botan/x509_dn.h>+#include <botan/pkix_types.h> #include <vector> #include <string> #include <map>
third_party/botan/src/lib/tls/tls_record.cpp view
@@ -340,11 +340,13 @@       BOTAN_ASSERT_EQUAL(readbuf.size(), TLS_HEADER_SIZE, "Have an entire header");       } -   const Protocol_Version version(readbuf[1], readbuf[2]);--   if(version.is_datagram_protocol())+   if(readbuf[1] != 3)+      {       throw TLS_Exception(Alert::PROTOCOL_VERSION,-                          "Expected TLS but got a record with DTLS version");+                          "Got unexpected TLS record version");+      }++   const Protocol_Version version(readbuf[1], readbuf[2]);     const size_t record_size = make_uint16(readbuf[TLS_HEADER_SIZE-2],                                           readbuf[TLS_HEADER_SIZE-1]);
third_party/botan/src/lib/tls/tls_record.h view
@@ -137,9 +137,9 @@ * @param message the record contents * @param message_len is size of message */-void write_unencrypted_record(secure_vector<uint8_t>& output,+void write_unencrypted_record(secure_vector<uint8_t>& write_buffer,                               uint8_t record_type,-                              Protocol_Version version,+                              Protocol_Version record_version,                               uint64_t record_sequence,                               const uint8_t* message,                               size_t message_len);
third_party/botan/src/lib/tls/tls_session.cpp view
@@ -9,7 +9,7 @@ #include <botan/loadstor.h> #include <botan/der_enc.h> #include <botan/ber_dec.h>-#include <botan/asn1_str.h>+#include <botan/asn1_obj.h> #include <botan/pem.h> #include <botan/aead.h> #include <botan/mac.h>
third_party/botan/src/lib/utils/compiler.h view
@@ -103,32 +103,23 @@ /* * Define BOTAN_DEPRECATED */-#if !defined(BOTAN_NO_DEPRECATED_WARNINGS)+#if !defined(BOTAN_NO_DEPRECATED_WARNINGS) && !defined(BOTAN_IS_BEING_BUILT) && !defined(BOTAN_AMALGAMATION_H_)    #if defined(__clang__)     #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated(msg)))     #define BOTAN_DEPRECATED_HEADER(hdr) _Pragma("message \"this header is deprecated\"")--    #if !defined(BOTAN_IS_BEING_BUILT) && !defined(BOTAN_AMALGAMATION_H_)-      #define BOTAN_FUTURE_INTERNAL_HEADER(hdr) _Pragma("message \"this header will be made internal in the future\"")-    #endif+    #define BOTAN_FUTURE_INTERNAL_HEADER(hdr) _Pragma("message \"this header will be made internal in the future\"")    #elif defined(_MSC_VER)     #define BOTAN_DEPRECATED(msg) __declspec(deprecated(msg))     #define BOTAN_DEPRECATED_HEADER(hdr) __pragma(message("this header is deprecated"))--    #if !defined(BOTAN_IS_BEING_BUILT) && !defined(BOTAN_AMALGAMATION_H_)-      #define BOTAN_FUTURE_INTERNAL_HEADER(hdr) __pragma(message("this header will be made internal in the future"))-    #endif+    #define BOTAN_FUTURE_INTERNAL_HEADER(hdr) __pragma(message("this header will be made internal in the future"))    #elif defined(__GNUC__)     /* msg supported since GCC 4.5, earliest we support is 4.8 */     #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated(msg)))     #define BOTAN_DEPRECATED_HEADER(hdr) _Pragma("GCC warning \"this header is deprecated\"")--    #if !defined(BOTAN_IS_BEING_BUILT) && !defined(BOTAN_AMALGAMATION_H_)-      #define BOTAN_FUTURE_INTERNAL_HEADER(hdr) _Pragma("GCC warning \"this header will be made internal in the future\"")-    #endif+    #define BOTAN_FUTURE_INTERNAL_HEADER(hdr) _Pragma("GCC warning \"this header will be made internal in the future\"")   #endif  #endif
third_party/botan/src/lib/utils/cpuid/cpuid.cpp view
@@ -40,6 +40,9 @@    CPUID_PRINT(sse42);    CPUID_PRINT(avx2);    CPUID_PRINT(avx512f);+   CPUID_PRINT(avx512dq);+   CPUID_PRINT(avx512bw);+   CPUID_PRINT(avx512_icelake);     CPUID_PRINT(rdtsc);    CPUID_PRINT(bmi1);@@ -51,6 +54,8 @@    CPUID_PRINT(rdrand);    CPUID_PRINT(rdseed);    CPUID_PRINT(intel_sha);+   CPUID_PRINT(avx512_aes);+   CPUID_PRINT(avx512_clmul); #endif  #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)@@ -164,6 +169,8 @@       return {Botan::CPUID::CPUID_AVX2_BIT};    if(tok == "avx512f")       return {Botan::CPUID::CPUID_AVX512F_BIT};+   if(tok == "avx512_icelake")+      return {Botan::CPUID::CPUID_AVX512_ICL_BIT};    // there were two if statements testing "sha" and "intel_sha" separately; combined    if(tok == "sha" || tok=="intel_sha")       return {Botan::CPUID::CPUID_SHA_BIT};@@ -179,6 +186,10 @@       return {Botan::CPUID::CPUID_RDRAND_BIT};    if(tok == "rdseed")       return {Botan::CPUID::CPUID_RDSEED_BIT};+   if(tok == "avx512_aes")+      return {Botan::CPUID::CPUID_AVX512_AES_BIT};+   if(tok == "avx512_clmul")+      return {Botan::CPUID::CPUID_AVX512_CLMUL_BIT};  #elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)    if(tok == "altivec" || tok == "simd")
third_party/botan/src/lib/utils/cpuid/cpuid.h view
@@ -97,25 +97,33 @@          // These values have no relation to cpuid bitfields           // SIMD instruction sets-         CPUID_SSE2_BIT    = (1ULL << 0),-         CPUID_SSSE3_BIT   = (1ULL << 1),-         CPUID_SSE41_BIT   = (1ULL << 2),-         CPUID_SSE42_BIT   = (1ULL << 3),-         CPUID_AVX2_BIT    = (1ULL << 4),-         CPUID_AVX512F_BIT = (1ULL << 5),+         CPUID_SSE2_BIT       = (1ULL << 0),+         CPUID_SSSE3_BIT      = (1ULL << 1),+         CPUID_SSE41_BIT      = (1ULL << 2),+         CPUID_SSE42_BIT      = (1ULL << 3),+         CPUID_AVX2_BIT       = (1ULL << 4),+         CPUID_AVX512F_BIT    = (1ULL << 5), -         // Misc useful instructions-         CPUID_RDTSC_BIT   = (1ULL << 10),-         CPUID_BMI2_BIT    = (1ULL << 11),-         CPUID_ADX_BIT     = (1ULL << 12),-         CPUID_BMI1_BIT    = (1ULL << 13),+         CPUID_AVX512DQ_BIT   = (1ULL << 6),+         CPUID_AVX512BW_BIT   = (1ULL << 7), +         // Ice Lake profile: AVX-512 F, DQ, BW, IFMA, VBMI, VBMI2, BITALG+         CPUID_AVX512_ICL_BIT = (1ULL << 11),+          // Crypto-specific ISAs-         CPUID_AESNI_BIT   = (1ULL << 16),-         CPUID_CLMUL_BIT   = (1ULL << 17),-         CPUID_RDRAND_BIT  = (1ULL << 18),-         CPUID_RDSEED_BIT  = (1ULL << 19),-         CPUID_SHA_BIT     = (1ULL << 20),+         CPUID_AESNI_BIT        = (1ULL << 16),+         CPUID_CLMUL_BIT        = (1ULL << 17),+         CPUID_RDRAND_BIT       = (1ULL << 18),+         CPUID_RDSEED_BIT       = (1ULL << 19),+         CPUID_SHA_BIT          = (1ULL << 20),+         CPUID_AVX512_AES_BIT   = (1ULL << 21),+         CPUID_AVX512_CLMUL_BIT = (1ULL << 22),++         // Misc useful instructions+         CPUID_RDTSC_BIT      = (1ULL << 48),+         CPUID_ADX_BIT        = (1ULL << 49),+         CPUID_BMI1_BIT       = (1ULL << 50),+         CPUID_BMI2_BIT       = (1ULL << 51), #endif  #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)@@ -267,6 +275,36 @@       */       static bool has_avx512f()          { return has_cpuid_bit(CPUID_AVX512F_BIT); }++      /**+      * Check if the processor supports AVX-512DQ+      */+      static bool has_avx512dq()+         { return has_cpuid_bit(CPUID_AVX512DQ_BIT); }++      /**+      * Check if the processor supports AVX-512BW+      */+      static bool has_avx512bw()+         { return has_cpuid_bit(CPUID_AVX512BW_BIT); }++      /**+      * Check if the processor supports AVX-512 Ice Lake profile+      */+      static bool has_avx512_icelake()+         { return has_cpuid_bit(CPUID_AVX512_ICL_BIT); }++      /**+      * Check if the processor supports AVX-512 AES (VAES)+      */+      static bool has_avx512_aes()+         { return has_cpuid_bit(CPUID_AVX512_AES_BIT); }++      /**+      * Check if the processor supports AVX-512 VPCLMULQDQ+      */+      static bool has_avx512_clmul()+         { return has_cpuid_bit(CPUID_AVX512_CLMUL_BIT); }        /**       * Check if the processor supports BMI1
third_party/botan/src/lib/utils/cpuid/cpuid_x86.cpp view
@@ -124,13 +124,23 @@          BMI1 = (1ULL << 3),          AVX2 = (1ULL << 5),          BMI2 = (1ULL << 8),-         AVX512F = (1ULL << 16),+         AVX512_F = (1ULL << 16),+         AVX512_DQ = (1ULL << 17),          RDSEED = (1ULL << 18),          ADX = (1ULL << 19),+         AVX512_IFMA = (1ULL << 21),          SHA = (1ULL << 29),+         AVX512_BW = (1ULL << 30),+         AVX512_VL = (1ULL << 31),+         AVX512_VBMI = (1ULL << 33),+         AVX512_VBMI2 = (1ULL << 38),+         AVX512_VAES = (1ULL << 41),+         AVX512_VCLMUL = (1ULL << 42),+         AVX512_VBITALG = (1ULL << 44),       };-      uint64_t flags7 = (static_cast<uint64_t>(cpuid[2]) << 32) | cpuid[1]; +      const uint64_t flags7 = (static_cast<uint64_t>(cpuid[2]) << 32) | cpuid[1];+       if(flags7 & x86_CPUID_7_bits::AVX2)          features_detected |= CPUID::CPUID_AVX2_BIT;       if(flags7 & x86_CPUID_7_bits::BMI1)@@ -145,8 +155,34 @@             features_detected |= CPUID::CPUID_BMI2_BIT;          } -      if(flags7 & x86_CPUID_7_bits::AVX512F)+      if(flags7 & x86_CPUID_7_bits::AVX512_F)+         {          features_detected |= CPUID::CPUID_AVX512F_BIT;++         if(flags7 & x86_CPUID_7_bits::AVX512_DQ)+            features_detected |= CPUID::CPUID_AVX512DQ_BIT;+         if(flags7 & x86_CPUID_7_bits::AVX512_BW)+            features_detected |= CPUID::CPUID_AVX512BW_BIT;++         const uint64_t ICELAKE_FLAGS =+            x86_CPUID_7_bits::AVX512_F |+            x86_CPUID_7_bits::AVX512_DQ |+            x86_CPUID_7_bits::AVX512_IFMA |+            x86_CPUID_7_bits::AVX512_BW |+            x86_CPUID_7_bits::AVX512_VL |+            x86_CPUID_7_bits::AVX512_VBMI |+            x86_CPUID_7_bits::AVX512_VBMI2 |+            x86_CPUID_7_bits::AVX512_VBITALG;++         if((flags7 & ICELAKE_FLAGS) == ICELAKE_FLAGS)+            features_detected |= CPUID::CPUID_AVX512_ICL_BIT;++         if(flags7 & x86_CPUID_7_bits::AVX512_VAES)+            features_detected |= CPUID::CPUID_AVX512_AES_BIT;+         if(flags7 & x86_CPUID_7_bits::AVX512_VCLMUL)+            features_detected |= CPUID::CPUID_AVX512_CLMUL_BIT;+         }+       if(flags7 & x86_CPUID_7_bits::RDSEED)          features_detected |= CPUID::CPUID_RDSEED_BIT;       if(flags7 & x86_CPUID_7_bits::ADX)
third_party/botan/src/lib/utils/ct_utils.h view
@@ -183,6 +183,30 @@          return ~Mask<T>::is_lt(x, y);          } +      static Mask<T> is_within_range(T v, T l, T u)+         {+         //return Mask<T>::is_gte(v, l) & Mask<T>::is_lte(v, u);++         const T v_lt_l = v^((v^l) | ((v-l)^v));+         const T v_gt_u = u^((u^v) | ((u-v)^u));+         const T either = v_lt_l | v_gt_u;+         return ~Mask<T>(expand_top_bit(either));+         }++      static Mask<T> is_any_of(T v, std::initializer_list<T> accepted)+         {+         T accept = 0;++         for(auto a: accepted)+            {+            const T diff = a ^ v;+            const T eq_zero = ~diff & (diff - 1);+            accept |= eq_zero;+            }++         return Mask<T>(expand_top_bit(accept));+         }+       /**       * AND-combine two masks       */
third_party/botan/src/lib/utils/ghash/ghash_cpu/ghash_cpu.cpp view
@@ -68,10 +68,16 @@       i2 = mask_lo.andc(i2);       } -   return SIMD_4x32((__vector unsigned int)__builtin_crypto_vpmsumd(-                       (__vector unsigned long)i1.raw(),-                       (__vector unsigned long)i2.raw())-      );+   auto i1v = reinterpret_cast<__vector unsigned long long>(i1.raw());+   auto i2v = reinterpret_cast<__vector unsigned long long>(i2.raw());++#if defined(__clang__)+   auto rv = __builtin_altivec_crypto_vpmsumd(i1v, i2v);+#else+   auto rv = __builtin_crypto_vpmsumd(i1v, i2v);+#endif++   return SIMD_4x32(reinterpret_cast<__vector unsigned int>(rv)); #endif    } 
third_party/botan/src/lib/utils/ghash/ghash_cpu/info.txt view
@@ -30,4 +30,5 @@ <cc> gcc:4.9 clang:3.8+msvc </cc>
third_party/botan/src/lib/utils/mem_ops.h view
@@ -224,6 +224,35 @@    return difference == 0;    } +template<typename T, typename Alloc>+size_t buffer_insert(std::vector<T, Alloc>& buf,+                     size_t buf_offset,+                     const T input[],+                     size_t input_length)+   {+   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());+   const size_t to_copy = std::min(input_length, buf.size() - buf_offset);+   if(to_copy > 0)+      {+      copy_mem(&buf[buf_offset], input, to_copy);+      }+   return to_copy;+   }++template<typename T, typename Alloc, typename Alloc2>+size_t buffer_insert(std::vector<T, Alloc>& buf,+                     size_t buf_offset,+                     const std::vector<T, Alloc2>& input)+   {+   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());+   const size_t to_copy = std::min(input.size(), buf.size() - buf_offset);+   if(to_copy > 0)+      {+      copy_mem(&buf[buf_offset], input.data(), to_copy);+      }+   return to_copy;+   }+ /** * XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length * @param out the input/output buffer
third_party/botan/src/lib/utils/parsing.cpp view
@@ -17,7 +17,7 @@ #include <set>  #if defined(BOTAN_HAS_ASN1)-  #include <botan/asn1_oid.h>+  #include <botan/asn1_obj.h> #endif  namespace Botan {@@ -324,8 +324,6 @@    return out;    } -namespace {- std::string tolower_string(const std::string& in)    {    std::string s = in;@@ -337,8 +335,6 @@       }    return s;    }--}  bool host_wildcard_match(const std::string& issued_, const std::string& host_)    {
third_party/botan/src/lib/utils/parsing.h view
@@ -167,6 +167,8 @@  std::string BOTAN_PUBLIC_API(2,0) clean_ws(const std::string& s); +std::string tolower_string(const std::string& s);+ /** * Check if the given hostname is a match for the specified wildcard */
third_party/botan/src/lib/utils/rotate.h view
@@ -69,14 +69,20 @@ template<> inline uint32_t rotl_var(uint32_t input, size_t rot)    {-   asm("roll %1,%0" : "+r" (input) : "c" (static_cast<uint8_t>(rot)));+   asm("roll %1,%0"+       : "+r" (input)+       : "c" (static_cast<uint8_t>(rot))+       : "cc");    return input;    }  template<> inline uint32_t rotr_var(uint32_t input, size_t rot)    {-   asm("rorl %1,%0" : "+r" (input) : "c" (static_cast<uint8_t>(rot)));+   asm("rorl %1,%0"+       : "+r" (input)+       : "c" (static_cast<uint8_t>(rot))+       : "cc");    return input;    } 
third_party/botan/src/lib/x509/asn1_alt_name.cpp view
@@ -6,14 +6,13 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/asn1_alt_name.h>+#include <botan/pkix_types.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/oids.h> #include <botan/internal/stl_util.h> #include <botan/parsing.h> #include <botan/loadstor.h>-#include <botan/x509_dn.h>  #include <sstream> 
third_party/botan/src/lib/x509/asn1_alt_name.h view
@@ -1,63 +1,11 @@ /*-* (C) 1999-2007 Jack Lloyd-*     2007 Yves Jerschow-* * Botan is released under the Simplified BSD License (see license.txt) */  #ifndef BOTAN_X509_ALT_NAME_H_ #define BOTAN_X509_ALT_NAME_H_ -#include <botan/asn1_obj.h>-#include <botan/asn1_str.h>-#include <botan/asn1_oid.h>-#include <botan/x509_dn.h>-#include <map>--namespace Botan {--/**-* Alternative Name-*/-class BOTAN_PUBLIC_API(2,0) AlternativeName final : public ASN1_Object-   {-   public:-      void encode_into(class DER_Encoder&) const override;-      void decode_from(class BER_Decoder&) override;--      std::multimap<std::string, std::string> contents() const;--      bool has_field(const std::string& attr) const;-      std::vector<std::string> get_attribute(const std::string& attr) const;--      std::string get_first_attribute(const std::string& attr) const;--      void add_attribute(const std::string& type, const std::string& value);-      void add_othername(const OID& oid, const std::string& value, ASN1_Tag type);--      const std::multimap<std::string, std::string>& get_attributes() const-         {-         return m_alt_info;-         }--      const std::multimap<OID, ASN1_String>& get_othernames() const-         {-         return m_othernames;-         }--      X509_DN dn() const;--      bool has_items() const;--      AlternativeName(const std::string& email_addr = "",-                      const std::string& uri = "",-                      const std::string& dns = "",-                      const std::string& ip_address = "");-   private:-      std::multimap<std::string, std::string> m_alt_info;-      std::multimap<OID, ASN1_String> m_othernames;-   };--}+#include <botan/pkix_types.h>+BOTAN_DEPRECATED_HEADER(asn1_alt_name.h)  #endif
+ third_party/botan/src/lib/x509/asn1_attribute.h view
@@ -0,0 +1,11 @@+/*+* Botan is released under the Simplified BSD License (see license.txt)+*/++#ifndef BOTAN_ASN1_ATTRIBUTE_H_+#define BOTAN_ASN1_ATTRIBUTE_H_++#include <botan/pkix_types.h>+BOTAN_DEPRECATED_HEADER(asn1_attribute.h)++#endif
third_party/botan/src/lib/x509/cert_status.cpp view
@@ -4,11 +4,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/cert_status.h>+#include <botan/pkix_enums.h>  namespace Botan { -//static const char* to_string(Certificate_Status_Code code)    {    switch(code)
third_party/botan/src/lib/x509/cert_status.h view
@@ -1,105 +1,11 @@ /*-* Path validation result enums-* (C) 2013 Jack Lloyd-* * Botan is released under the Simplified BSD License (see license.txt) */  #ifndef BOTAN_X509_PATH_RESULT_H_ #define BOTAN_X509_PATH_RESULT_H_ -#include <botan/types.h>--namespace Botan {--/**-* Certificate validation status code-*/-enum class Certificate_Status_Code {-   OK = 0,-   VERIFIED = 0,--   // Revocation status-   OCSP_RESPONSE_GOOD = 1,-   OCSP_SIGNATURE_OK = 2,-   VALID_CRL_CHECKED = 3,-   OCSP_NO_HTTP = 4,--   // Warnings-   FIRST_WARNING_STATUS = 500,-   CERT_SERIAL_NEGATIVE = 500,-   DN_TOO_LONG = 501,-   OCSP_NO_REVOCATION_URL = 502,-   OCSP_SERVER_NOT_AVAILABLE = 503,--   // Typo versions of above - will be removed in future major release-   OSCP_NO_REVOCATION_URL = 502,-   OSCP_SERVER_NOT_AVAILABLE = 503,--   // Errors-   FIRST_ERROR_STATUS = 1000,--   SIGNATURE_METHOD_TOO_WEAK = 1000,-   UNTRUSTED_HASH = 1001,-   NO_REVOCATION_DATA = 1002,-   NO_MATCHING_CRLDP = 1003,--   // Time problems-   CERT_NOT_YET_VALID = 2000,-   CERT_HAS_EXPIRED = 2001,-   OCSP_NOT_YET_VALID = 2002,-   OCSP_HAS_EXPIRED = 2003,-   CRL_NOT_YET_VALID = 2004,-   CRL_HAS_EXPIRED = 2005,-   OCSP_IS_TOO_OLD = 2006,--   // Chain generation problems-   CERT_ISSUER_NOT_FOUND = 3000,-   CANNOT_ESTABLISH_TRUST = 3001,-   CERT_CHAIN_LOOP = 3002,-   CHAIN_LACKS_TRUST_ROOT = 3003,-   CHAIN_NAME_MISMATCH = 3004,--   // Validation errors-   POLICY_ERROR = 4000,-   INVALID_USAGE = 4001,-   CERT_CHAIN_TOO_LONG = 4002,-   CA_CERT_NOT_FOR_CERT_ISSUER = 4003,-   NAME_CONSTRAINT_ERROR = 4004,--   // Revocation errors-   CA_CERT_NOT_FOR_CRL_ISSUER = 4005,-   OCSP_CERT_NOT_LISTED = 4006,-   OCSP_BAD_STATUS = 4007,--   // Other problems-   CERT_NAME_NOMATCH = 4008,-   UNKNOWN_CRITICAL_EXTENSION = 4009,-   DUPLICATE_CERT_EXTENSION = 4010,-   OCSP_SIGNATURE_ERROR = 4501,-   OCSP_ISSUER_NOT_FOUND = 4502,-   OCSP_RESPONSE_MISSING_KEYUSAGE = 4503,-   OCSP_RESPONSE_INVALID = 4504,-   EXT_IN_V1_V2_CERT = 4505,-   DUPLICATE_CERT_POLICY = 4506,-   V2_IDENTIFIERS_IN_V1_CERT = 4507,--   // Hard failures-   CERT_IS_REVOKED = 5000,-   CRL_BAD_SIGNATURE = 5001,-   SIGNATURE_ERROR = 5002,-   CERT_PUBKEY_INVALID = 5003,-   SIGNATURE_ALGO_UNKNOWN = 5004,-   SIGNATURE_ALGO_BAD_PARAMS = 5005-};--/**-* Convert a status code to a human readable diagnostic message-* @param code the certifcate status-* @return string literal constant, or nullptr if code unknown-*/-BOTAN_PUBLIC_API(2,0) const char* to_string(Certificate_Status_Code code);--}+#include <botan/pkix_enums.h>+BOTAN_DEPRECATED_HEADER(cert_status.h)  #endif
third_party/botan/src/lib/x509/certstor.cpp view
@@ -7,6 +7,7 @@ */  #include <botan/certstor.h>+#include <botan/pkix_types.h> #include <botan/internal/filesystem.h> #include <botan/hash.h> #include <botan/data_src.h>
third_party/botan/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp view
@@ -6,11 +6,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/build.h>- #include <botan/certstor_flatfile.h>+#include <botan/pkix_types.h> #include <botan/data_src.h> #include <botan/pem.h>+#include <stdexcept>  namespace Botan { namespace {
third_party/botan/src/lib/x509/certstor_sql/certstor_sql.cpp view
@@ -11,6 +11,7 @@ #include <botan/ber_dec.h> #include <botan/pkcs8.h> #include <botan/data_src.h>+#include <botan/pkix_types.h>  namespace Botan { 
third_party/botan/src/lib/x509/certstor_system/certstor_system.cpp view
@@ -5,6 +5,7 @@ */  #include <botan/certstor_system.h>+#include <botan/pkix_types.h> #include <botan/x509cert.h>  #if defined(BOTAN_HAS_CERTSTOR_MACOS)
third_party/botan/src/lib/x509/certstor_system_macos/certstor_macos.cpp view
@@ -6,22 +6,19 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/build.h>- #include <algorithm> #include <array> -#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0-#include <CoreFoundation/CoreFoundation.h>-#include <CoreServices/CoreServices.h>--#include <botan/assert.h> #include <botan/ber_dec.h> #include <botan/certstor_macos.h> #include <botan/data_src.h> #include <botan/der_enc.h> #include <botan/exceptn.h>-#include <botan/x509_dn.h>+#include <botan/pkix_types.h>++#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0+#include <CoreFoundation/CoreFoundation.h>+#include <CoreServices/CoreServices.h>  namespace Botan { 
third_party/botan/src/lib/x509/certstor_system_windows/certstor_windows.cpp view
@@ -7,6 +7,7 @@ */  #include <botan/certstor_windows.h>+#include <botan/pkix_types.h> #include <botan/der_enc.h>  #include <array>
third_party/botan/src/lib/x509/crl_ent.cpp view
@@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/crl_ent.h>+#include <botan/x509_crl.h> #include <botan/x509cert.h> #include <botan/x509_ext.h> #include <botan/der_enc.h>
third_party/botan/src/lib/x509/crl_ent.h view
@@ -1,106 +1,11 @@ /*-* CRL Entry-* (C) 1999-2007 Jack Lloyd-* * Botan is released under the Simplified BSD License (see license.txt) */  #ifndef BOTAN_CRL_ENTRY_H_ #define BOTAN_CRL_ENTRY_H_ -#include <botan/asn1_time.h>--namespace Botan {--class Extensions;-class X509_Certificate;-struct CRL_Entry_Data;--/**-* X.509v2 CRL Reason Code.-* This will become an enum class in a future major release-*/-enum CRL_Code : uint32_t {-   UNSPECIFIED            = 0,-   KEY_COMPROMISE         = 1,-   CA_COMPROMISE          = 2,-   AFFILIATION_CHANGED    = 3,-   SUPERSEDED             = 4,-   CESSATION_OF_OPERATION = 5,-   CERTIFICATE_HOLD       = 6,-   REMOVE_FROM_CRL        = 8,-   PRIVLEDGE_WITHDRAWN    = 9,-   PRIVILEGE_WITHDRAWN    = 9,-   AA_COMPROMISE          = 10,--   DELETE_CRL_ENTRY       = 0xFF00,-   OCSP_GOOD              = 0xFF01,-   OCSP_UNKNOWN           = 0xFF02-};--/**-* This class represents CRL entries-*/-class BOTAN_PUBLIC_API(2,0) CRL_Entry final : public ASN1_Object-   {-   public:-      void encode_into(class DER_Encoder&) const override;-      void decode_from(class BER_Decoder&) override;--      /**-      * Get the serial number of the certificate associated with this entry.-      * @return certificate's serial number-      */-      const std::vector<uint8_t>& serial_number() const;--      /**-      * Get the revocation date of the certificate associated with this entry-      * @return certificate's revocation date-      */-      const X509_Time& expire_time() const;--      /**-      * Get the entries reason code-      * @return reason code-      */-      CRL_Code reason_code() const;--      /**-      * Get the extensions on this CRL entry-      */-      const Extensions& extensions() const;--      /**-      * Create uninitialized CRL_Entry object-      */-      CRL_Entry() = default;--      /**-      * Construct an CRL entry.-      * @param cert the certificate to revoke-      * @param reason the reason code to set in the entry-      */-      CRL_Entry(const X509_Certificate& cert,-                CRL_Code reason = UNSPECIFIED);--   private:-      friend class X509_CRL;--      const CRL_Entry_Data& data() const;--      std::shared_ptr<CRL_Entry_Data> m_data;-   };--/**-* Test two CRL entries for equality in all fields.-*/-BOTAN_PUBLIC_API(2,0) bool operator==(const CRL_Entry&, const CRL_Entry&);--/**-* Test two CRL entries for inequality in at least one field.-*/-BOTAN_PUBLIC_API(2,0) bool operator!=(const CRL_Entry&, const CRL_Entry&);--}+#include <botan/x509_crl.h>+BOTAN_DEPRECATED_HEADER(crl_ent.h)  #endif
third_party/botan/src/lib/x509/datastor.h view
@@ -8,8 +8,7 @@ #ifndef BOTAN_DATA_STORE_H_ #define BOTAN_DATA_STORE_H_ -#include <botan/x509_dn.h>-#include <botan/asn1_alt_name.h>+#include <botan/pkix_types.h> #include <functional> #include <string> #include <vector>
third_party/botan/src/lib/x509/key_constraint.cpp view
@@ -6,7 +6,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/key_constraint.h>+#include <botan/pkix_types.h> #include <botan/pk_keys.h> #include <vector> 
third_party/botan/src/lib/x509/key_constraint.h view
@@ -1,49 +1,11 @@ /*-* Enumerations-* (C) 1999-2007 Jack Lloyd-* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity-* * Botan is released under the Simplified BSD License (see license.txt) */ -#ifndef BOTAN_ENUMS_H_-#define BOTAN_ENUMS_H_--#include <botan/types.h>-#include <string>--namespace Botan {--/**-* X.509v3 Key Constraints.-* If updating update copy in ffi.h-*/-enum Key_Constraints {-   NO_CONSTRAINTS     = 0,-   DIGITAL_SIGNATURE  = 1 << 15,-   NON_REPUDIATION    = 1 << 14,-   KEY_ENCIPHERMENT   = 1 << 13,-   DATA_ENCIPHERMENT  = 1 << 12,-   KEY_AGREEMENT      = 1 << 11,-   KEY_CERT_SIGN      = 1 << 10,-   CRL_SIGN           = 1 << 9,-   ENCIPHER_ONLY      = 1 << 8,-   DECIPHER_ONLY      = 1 << 7-};--class Public_Key;--/**-* Check that key constraints are permitted for a specific public key.-* @param pub_key the public key on which the constraints shall be enforced on-* @param constraints the constraints that shall be enforced on the key-* @throw Invalid_Argument if the given constraints are not permitted for this key-*/-BOTAN_PUBLIC_API(2,0) void verify_cert_constraints_valid_for_key_type(const Public_Key& pub_key,-                                                                Key_Constraints constraints);--std::string BOTAN_PUBLIC_API(2,0) key_constraints_to_string(Key_Constraints);+#ifndef BOTAN_KEY_CONSTRAINT_H_+#define BOTAN_KEY_CONSTRAINT_H_ -}+#include <botan/pkix_enums.h>+BOTAN_DEPRECATED_HEADER(key_constraint.h)  #endif
third_party/botan/src/lib/x509/name_constraint.cpp view
@@ -5,11 +5,9 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/name_constraint.h>-#include <botan/asn1_alt_name.h>+#include <botan/pkix_types.h> #include <botan/ber_dec.h> #include <botan/loadstor.h>-#include <botan/x509_dn.h> #include <botan/x509cert.h> #include <botan/parsing.h> #include <sstream>@@ -167,17 +165,19 @@    {    if(nam.size() == name().size())       {-      return nam == name();+      return tolower_string(nam) == tolower_string(name());       }    else if(name().size() > nam.size())       {+      // The constraint is longer than the issued name: not possibly a match       return false;       }    else // name.size() < nam.size()       {-      std::string constr = name().front() == '.' ? name() : "." + name();       // constr is suffix of nam-      return constr == nam.substr(nam.size() - constr.size(), constr.size());+      const std::string constr = name().front() == '.' ? name() : "." + name();+      const std::string substr = nam.substr(nam.size() - constr.size(), constr.size());+      return tolower_string(constr) == tolower_string(substr);       }    } 
third_party/botan/src/lib/x509/name_constraint.h view
@@ -1,182 +1,11 @@ /*-* X.509 Name Constraint-* (C) 2015 Kai Michaelis-* * Botan is released under the Simplified BSD License (see license.txt) */  #ifndef BOTAN_NAME_CONSTRAINT_H_ #define BOTAN_NAME_CONSTRAINT_H_ -#include <botan/asn1_obj.h>-#include <ostream>-#include <limits>--namespace Botan {--class BER_Encoder;-class DER_Encoder;-class X509_Certificate;--/**-* @brief X.509 GeneralName Type-*-* Handles parsing GeneralName types in their BER and canonical string-* encoding. Allows matching GeneralNames against each other using-* the rules laid out in the RFC 5280, sec. 4.2.1.10 (Name Contraints).-*/-class BOTAN_PUBLIC_API(2,0) GeneralName final : public ASN1_Object-   {-   public:-      enum MatchResult : int-            {-            All,-            Some,-            None,-            NotFound,-            UnknownType,-            };--      /**-      * Creates an empty GeneralName.-      */-      GeneralName() = default;--      /**-      * Creates a new GeneralName for its string format.-      * @param str type and name, colon-separated, e.g., "DNS:google.com"-      */-      GeneralName(const std::string& str);--      void encode_into(DER_Encoder&) const override;--      void decode_from(BER_Decoder&) override;--      /**-      * @return Type of the name. Can be DN, DNS, IP, RFC822 or URI.-      */-      const std::string& type() const { return m_type; }--      /**-      * @return The name as string. Format depends on type.-      */-      const std::string& name() const { return m_name; }--      /**-      * Checks whether a given certificate (partially) matches this name.-      * @param cert certificate to be matched-      * @return the match result-      */-      MatchResult matches(const X509_Certificate& cert) const;--   private:-      std::string m_type;-      std::string m_name;--      bool matches_dns(const std::string&) const;-      bool matches_dn(const std::string&) const;-      bool matches_ip(const std::string&) const;-   };--std::ostream& operator<<(std::ostream& os, const GeneralName& gn);--/**-* @brief A single Name Constraint-*-* The Name Constraint extension adds a minimum and maximum path-* length to a GeneralName to form a constraint. The length limits-* are currently unused.-*/-class BOTAN_PUBLIC_API(2,0) GeneralSubtree final : public ASN1_Object-   {-   public:-      /**-      * Creates an empty name constraint.-      */-      GeneralSubtree() : m_base(), m_minimum(0), m_maximum(std::numeric_limits<std::size_t>::max())-      {}--      /***-      * Creates a new name constraint.-      * @param base name-      * @param min minimum path length-      * @param max maximum path length-      */-      GeneralSubtree(const GeneralName& base, size_t min, size_t max)-      : m_base(base), m_minimum(min), m_maximum(max)-      {}--      /**-      * Creates a new name constraint for its string format.-      * @param str name constraint-      */-      GeneralSubtree(const std::string& str);--      void encode_into(DER_Encoder&) const override;--      void decode_from(BER_Decoder&) override;--      /**-      * @return name-      */-      const GeneralName& base() const { return m_base; }--      /**-      * @return minimum path length-      */-      size_t minimum() const { return m_minimum; }--      /**-      * @return maximum path length-      */-      size_t maximum() const { return m_maximum; }--   private:-      GeneralName m_base;-      size_t m_minimum;-      size_t m_maximum;-   };--std::ostream& operator<<(std::ostream& os, const GeneralSubtree& gs);--/**-* @brief Name Constraints-*-* Wraps the Name Constraints associated with a certificate.-*/-class BOTAN_PUBLIC_API(2,0) NameConstraints final-   {-   public:-      /**-      * Creates an empty name NameConstraints.-      */-      NameConstraints() : m_permitted_subtrees(), m_excluded_subtrees() {}--      /**-      * Creates NameConstraints from a list of permitted and excluded subtrees.-      * @param permitted_subtrees names for which the certificate is permitted-      * @param excluded_subtrees names for which the certificate is not permitted-      */-      NameConstraints(std::vector<GeneralSubtree>&& permitted_subtrees,-                    std::vector<GeneralSubtree>&& excluded_subtrees)-      : m_permitted_subtrees(permitted_subtrees), m_excluded_subtrees(excluded_subtrees)-      {}--      /**-      * @return permitted names-      */-      const std::vector<GeneralSubtree>& permitted() const { return m_permitted_subtrees; }--      /**-      * @return excluded names-      */-      const std::vector<GeneralSubtree>& excluded() const { return m_excluded_subtrees; }--   private:-      std::vector<GeneralSubtree> m_permitted_subtrees;-      std::vector<GeneralSubtree> m_excluded_subtrees;-};--}+#include <botan/pkix_types.h>+BOTAN_DEPRECATED_HEADER(name_constraint.h)  #endif
third_party/botan/src/lib/x509/ocsp.h view
@@ -8,9 +8,10 @@ #ifndef BOTAN_OCSP_H_ #define BOTAN_OCSP_H_ -#include <botan/cert_status.h>-#include <botan/ocsp_types.h>-#include <botan/x509_dn.h>+#include <botan/asn1_obj.h>+#include <botan/pkix_types.h>+#include <botan/x509cert.h>+#include <botan/bigint.h> #include <chrono>  namespace Botan {@@ -18,6 +19,51 @@ class Certificate_Store;  namespace OCSP {++class BOTAN_PUBLIC_API(2,0) CertID final : public ASN1_Object+   {+   public:+      CertID() = default;++      CertID(const X509_Certificate& issuer,+             const BigInt& subject_serial);++      bool is_id_for(const X509_Certificate& issuer,+                     const X509_Certificate& subject) const;++      void encode_into(class DER_Encoder& to) const override;++      void decode_from(class BER_Decoder& from) override;++      const std::vector<uint8_t>& issuer_key_hash() const { return m_issuer_key_hash; }++   private:+      AlgorithmIdentifier m_hash_id;+      std::vector<uint8_t> m_issuer_dn_hash;+      std::vector<uint8_t> m_issuer_key_hash;+      BigInt m_subject_serial;+   };++class BOTAN_PUBLIC_API(2,0) SingleResponse final : public ASN1_Object+   {+   public:+      const CertID& certid() const { return m_certid; }++      size_t cert_status() const { return m_cert_status; }++      X509_Time this_update() const { return m_thisupdate; }++      X509_Time next_update() const { return m_nextupdate; }++      void encode_into(class DER_Encoder& to) const override;++      void decode_from(class BER_Decoder& from) override;+   private:+      CertID m_certid;+      size_t m_cert_status = 2; // unknown+      X509_Time m_thisupdate;+      X509_Time m_nextupdate;+   };  /** * An OCSP request.
third_party/botan/src/lib/x509/ocsp_types.cpp view
@@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/ocsp_types.h>+#include <botan/ocsp.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/x509_ext.h>
third_party/botan/src/lib/x509/ocsp_types.h view
@@ -1,68 +1,11 @@ /*-* OCSP subtypes-* (C) 2012 Jack Lloyd-* * Botan is released under the Simplified BSD License (see license.txt) */  #ifndef BOTAN_OCSP_TYPES_H_ #define BOTAN_OCSP_TYPES_H_ -#include <botan/x509cert.h>-#include <botan/asn1_time.h>-#include <botan/bigint.h>--namespace Botan {--namespace OCSP {--class BOTAN_PUBLIC_API(2,0) CertID final : public ASN1_Object-   {-   public:-      CertID() = default;--      CertID(const X509_Certificate& issuer,-             const BigInt& subject_serial);--      bool is_id_for(const X509_Certificate& issuer,-                     const X509_Certificate& subject) const;--      void encode_into(class DER_Encoder& to) const override;--      void decode_from(class BER_Decoder& from) override;--      const std::vector<uint8_t>& issuer_key_hash() const { return m_issuer_key_hash; }--   private:-      AlgorithmIdentifier m_hash_id;-      std::vector<uint8_t> m_issuer_dn_hash;-      std::vector<uint8_t> m_issuer_key_hash;-      BigInt m_subject_serial;-   };--class BOTAN_PUBLIC_API(2,0) SingleResponse final : public ASN1_Object-   {-   public:-      const CertID& certid() const { return m_certid; }--      size_t cert_status() const { return m_cert_status; }--      X509_Time this_update() const { return m_thisupdate; }--      X509_Time next_update() const { return m_nextupdate; }--      void encode_into(class DER_Encoder& to) const override;--      void decode_from(class BER_Decoder& from) override;-   private:-      CertID m_certid;-      size_t m_cert_status = 2; // unknown-      X509_Time m_thisupdate;-      X509_Time m_nextupdate;-   };--}--}+#include <botan/ocsp.h>+BOTAN_DEPRECATED_HEADER(ocsp_types.h)  #endif
third_party/botan/src/lib/x509/pkcs10.cpp view
@@ -6,6 +6,7 @@ */  #include <botan/pkcs10.h>+#include <botan/x509_key.h> #include <botan/x509_ext.h> #include <botan/x509cert.h> #include <botan/ber_dec.h>
third_party/botan/src/lib/x509/pkcs10.h view
@@ -10,17 +10,17 @@ #define BOTAN_PKCS10_H_  #include <botan/x509_obj.h>-#include <botan/x509_dn.h>-#include <botan/key_constraint.h>-#include <botan/asn1_attribute.h>-#include <botan/asn1_alt_name.h>+#include <botan/pkix_enums.h> #include <vector>  namespace Botan { +struct PKCS10_Data;+ class Private_Key; class Extensions;-struct PKCS10_Data;+class X509_DN;+class AlternativeName;  /** * PKCS #10 Certificate Request.
+ third_party/botan/src/lib/x509/pkix_enums.h view
@@ -0,0 +1,143 @@+/*+* (C) 2013 Jack Lloyd+*+* Botan is released under the Simplified BSD License (see license.txt)+*/++#ifndef BOTAN_X509_PKIX_ENUMS_H_+#define BOTAN_X509_PKIX_ENUMS_H_++#include <botan/types.h>++namespace Botan {++/**+* Certificate validation status code+*/+enum class Certificate_Status_Code {+   OK = 0,+   VERIFIED = 0,++   // Revocation status+   OCSP_RESPONSE_GOOD = 1,+   OCSP_SIGNATURE_OK = 2,+   VALID_CRL_CHECKED = 3,+   OCSP_NO_HTTP = 4,++   // Warnings+   FIRST_WARNING_STATUS = 500,+   CERT_SERIAL_NEGATIVE = 500,+   DN_TOO_LONG = 501,+   OCSP_NO_REVOCATION_URL = 502,+   OCSP_SERVER_NOT_AVAILABLE = 503,++   // Typo versions of above - will be removed in future major release+   OSCP_NO_REVOCATION_URL = 502,+   OSCP_SERVER_NOT_AVAILABLE = 503,++   // Errors+   FIRST_ERROR_STATUS = 1000,++   SIGNATURE_METHOD_TOO_WEAK = 1000,+   UNTRUSTED_HASH = 1001,+   NO_REVOCATION_DATA = 1002,+   NO_MATCHING_CRLDP = 1003,++   // Time problems+   CERT_NOT_YET_VALID = 2000,+   CERT_HAS_EXPIRED = 2001,+   OCSP_NOT_YET_VALID = 2002,+   OCSP_HAS_EXPIRED = 2003,+   CRL_NOT_YET_VALID = 2004,+   CRL_HAS_EXPIRED = 2005,+   OCSP_IS_TOO_OLD = 2006,++   // Chain generation problems+   CERT_ISSUER_NOT_FOUND = 3000,+   CANNOT_ESTABLISH_TRUST = 3001,+   CERT_CHAIN_LOOP = 3002,+   CHAIN_LACKS_TRUST_ROOT = 3003,+   CHAIN_NAME_MISMATCH = 3004,++   // Validation errors+   POLICY_ERROR = 4000,+   INVALID_USAGE = 4001,+   CERT_CHAIN_TOO_LONG = 4002,+   CA_CERT_NOT_FOR_CERT_ISSUER = 4003,+   NAME_CONSTRAINT_ERROR = 4004,++   // Revocation errors+   CA_CERT_NOT_FOR_CRL_ISSUER = 4005,+   OCSP_CERT_NOT_LISTED = 4006,+   OCSP_BAD_STATUS = 4007,++   // Other problems+   CERT_NAME_NOMATCH = 4008,+   UNKNOWN_CRITICAL_EXTENSION = 4009,+   DUPLICATE_CERT_EXTENSION = 4010,+   OCSP_SIGNATURE_ERROR = 4501,+   OCSP_ISSUER_NOT_FOUND = 4502,+   OCSP_RESPONSE_MISSING_KEYUSAGE = 4503,+   OCSP_RESPONSE_INVALID = 4504,+   EXT_IN_V1_V2_CERT = 4505,+   DUPLICATE_CERT_POLICY = 4506,+   V2_IDENTIFIERS_IN_V1_CERT = 4507,++   // Hard failures+   CERT_IS_REVOKED = 5000,+   CRL_BAD_SIGNATURE = 5001,+   SIGNATURE_ERROR = 5002,+   CERT_PUBKEY_INVALID = 5003,+   SIGNATURE_ALGO_UNKNOWN = 5004,+   SIGNATURE_ALGO_BAD_PARAMS = 5005+};++/**+* Convert a status code to a human readable diagnostic message+* @param code the certifcate status+* @return string literal constant, or nullptr if code unknown+*/+BOTAN_PUBLIC_API(2,0) const char* to_string(Certificate_Status_Code code);++/**+* X.509v3 Key Constraints.+* If updating update copy in ffi.h+*/+enum Key_Constraints {+   NO_CONSTRAINTS     = 0,+   DIGITAL_SIGNATURE  = 1 << 15,+   NON_REPUDIATION    = 1 << 14,+   KEY_ENCIPHERMENT   = 1 << 13,+   DATA_ENCIPHERMENT  = 1 << 12,+   KEY_AGREEMENT      = 1 << 11,+   KEY_CERT_SIGN      = 1 << 10,+   CRL_SIGN           = 1 << 9,+   ENCIPHER_ONLY      = 1 << 8,+   DECIPHER_ONLY      = 1 << 7+};++/**+* X.509v2 CRL Reason Code.+* This will become an enum class in a future major release+*/+enum CRL_Code : uint32_t {+   UNSPECIFIED            = 0,+   KEY_COMPROMISE         = 1,+   CA_COMPROMISE          = 2,+   AFFILIATION_CHANGED    = 3,+   SUPERSEDED             = 4,+   CESSATION_OF_OPERATION = 5,+   CERTIFICATE_HOLD       = 6,+   REMOVE_FROM_CRL        = 8,+   PRIVLEDGE_WITHDRAWN    = 9,+   PRIVILEGE_WITHDRAWN    = 9,+   AA_COMPROMISE          = 10,++   DELETE_CRL_ENTRY       = 0xFF00,+   OCSP_GOOD              = 0xFF01,+   OCSP_UNKNOWN           = 0xFF02+};++}++#endif
+ third_party/botan/src/lib/x509/pkix_types.h view
@@ -0,0 +1,613 @@+/*+* (C) 1999-2010,2012,2018,2020 Jack Lloyd+* (C) 2007 Yves Jerschow+* (C) 2015 Kai Michaelis+* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity+* (C) 2017 Fabian Weissberg, Rohde & Schwarz Cybersecurity+*+* Botan is released under the Simplified BSD License (see license.txt)+*/++#ifndef BOTAN_PKIX_TYPES_H_+#define BOTAN_PKIX_TYPES_H_++#include <botan/asn1_obj.h>+#include <botan/pkix_enums.h>+#include <vector>+#include <string>+#include <iosfwd>+#include <map>+#include <set>++namespace Botan {++class X509_Certificate;+class Data_Store;+class Public_Key;++/**+* Check that key constraints are permitted for a specific public key.+* @param pub_key the public key on which the constraints shall be enforced on+* @param constraints the constraints that shall be enforced on the key+* @throw Invalid_Argument if the given constraints are not permitted for this key+*/+BOTAN_PUBLIC_API(2,0) void verify_cert_constraints_valid_for_key_type(const Public_Key& pub_key,+                                                                      Key_Constraints constraints);++std::string BOTAN_PUBLIC_API(2,0) key_constraints_to_string(Key_Constraints);++/**+* Distinguished Name+*/+class BOTAN_PUBLIC_API(2,0) X509_DN final : public ASN1_Object+   {+   public:+      X509_DN() = default;++      explicit X509_DN(const std::multimap<OID, std::string>& args)+         {+         for(auto i : args)+            add_attribute(i.first, i.second);+         }++      explicit X509_DN(const std::multimap<std::string, std::string>& args)+         {+         for(auto i : args)+            add_attribute(i.first, i.second);+         }++      void encode_into(DER_Encoder&) const override;+      void decode_from(BER_Decoder&) override;++      bool has_field(const OID& oid) const;+      ASN1_String get_first_attribute(const OID& oid) const;++      /*+      * Return the BER encoded data, if any+      */+      const std::vector<uint8_t>& get_bits() const { return m_dn_bits; }++      bool empty() const { return m_rdn.empty(); }++      std::string to_string() const;++      const std::vector<std::pair<OID,ASN1_String>>& dn_info() const { return m_rdn; }++      std::multimap<OID, std::string> get_attributes() const;+      std::multimap<std::string, std::string> contents() const;++      bool has_field(const std::string& attr) const;+      std::vector<std::string> get_attribute(const std::string& attr) const;+      std::string get_first_attribute(const std::string& attr) const;++      void add_attribute(const std::string& key, const std::string& val);++      void add_attribute(const OID& oid, const std::string& val)+         {+         add_attribute(oid, ASN1_String(val));+         }++      void add_attribute(const OID& oid, const ASN1_String& val);++      static std::string deref_info_field(const std::string& key);++      /**+      * Lookup upper bounds in characters for the length of distinguished name fields+      * as given in RFC 5280, Appendix A.+      *+      * @param oid the oid of the DN to lookup+      * @return the upper bound, or zero if no ub is known to Botan+      */+      static size_t lookup_ub(const OID& oid);++   private:+      std::vector<std::pair<OID,ASN1_String>> m_rdn;+      std::vector<uint8_t> m_dn_bits;+   };++bool BOTAN_PUBLIC_API(2,0) operator==(const X509_DN& dn1, const X509_DN& dn2);+bool BOTAN_PUBLIC_API(2,0) operator!=(const X509_DN& dn1, const X509_DN& dn2);++/*+The ordering here is arbitrary and may change from release to release.+It is intended for allowing DNs as keys in std::map and similiar containers+*/+bool BOTAN_PUBLIC_API(2,0) operator<(const X509_DN& dn1, const X509_DN& dn2);++BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream& out, const X509_DN& dn);+BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream& in, X509_DN& dn);++/**+* Alternative Name+*/+class BOTAN_PUBLIC_API(2,0) AlternativeName final : public ASN1_Object+   {+   public:+      void encode_into(DER_Encoder&) const override;+      void decode_from(BER_Decoder&) override;++      std::multimap<std::string, std::string> contents() const;++      bool has_field(const std::string& attr) const;+      std::vector<std::string> get_attribute(const std::string& attr) const;++      std::string get_first_attribute(const std::string& attr) const;++      void add_attribute(const std::string& type, const std::string& value);+      void add_othername(const OID& oid, const std::string& value, ASN1_Tag type);++      const std::multimap<std::string, std::string>& get_attributes() const+         {+         return m_alt_info;+         }++      const std::multimap<OID, ASN1_String>& get_othernames() const+         {+         return m_othernames;+         }++      X509_DN dn() const;++      bool has_items() const;++      AlternativeName(const std::string& email_addr = "",+                      const std::string& uri = "",+                      const std::string& dns = "",+                      const std::string& ip_address = "");+   private:+      std::multimap<std::string, std::string> m_alt_info;+      std::multimap<OID, ASN1_String> m_othernames;+   };++/**+* Attribute+*/+class BOTAN_PUBLIC_API(2,0) Attribute final : public ASN1_Object+   {+   public:+      void encode_into(DER_Encoder& to) const override;+      void decode_from(BER_Decoder& from) override;++      Attribute() = default;+      Attribute(const OID&, const std::vector<uint8_t>&);+      Attribute(const std::string&, const std::vector<uint8_t>&);++      const OID& get_oid() const { return oid; }++      const std::vector<uint8_t>& get_parameters() const { return parameters; }++   BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES:+      /*+      * These values are public for historical reasons, but in a future release+      * they will be made private. Do not access them.+      */+      OID oid;+      std::vector<uint8_t> parameters;+   };++/**+* @brief X.509 GeneralName Type+*+* Handles parsing GeneralName types in their BER and canonical string+* encoding. Allows matching GeneralNames against each other using+* the rules laid out in the RFC 5280, sec. 4.2.1.10 (Name Contraints).+*/+class BOTAN_PUBLIC_API(2,0) GeneralName final : public ASN1_Object+   {+   public:+      enum MatchResult : int+            {+            All,+            Some,+            None,+            NotFound,+            UnknownType,+            };++      /**+      * Creates an empty GeneralName.+      */+      GeneralName() = default;++      /**+      * Creates a new GeneralName for its string format.+      * @param str type and name, colon-separated, e.g., "DNS:google.com"+      */+      GeneralName(const std::string& str);++      void encode_into(DER_Encoder&) const override;++      void decode_from(BER_Decoder&) override;++      /**+      * @return Type of the name. Can be DN, DNS, IP, RFC822 or URI.+      */+      const std::string& type() const { return m_type; }++      /**+      * @return The name as string. Format depends on type.+      */+      const std::string& name() const { return m_name; }++      /**+      * Checks whether a given certificate (partially) matches this name.+      * @param cert certificate to be matched+      * @return the match result+      */+      MatchResult matches(const X509_Certificate& cert) const;++   private:+      std::string m_type;+      std::string m_name;++      bool matches_dns(const std::string&) const;+      bool matches_dn(const std::string&) const;+      bool matches_ip(const std::string&) const;+   };++std::ostream& operator<<(std::ostream& os, const GeneralName& gn);++/**+* @brief A single Name Constraint+*+* The Name Constraint extension adds a minimum and maximum path+* length to a GeneralName to form a constraint. The length limits+* are currently unused.+*/+class BOTAN_PUBLIC_API(2,0) GeneralSubtree final : public ASN1_Object+   {+   public:+      /**+      * Creates an empty name constraint.+      */+      GeneralSubtree() : m_base(), m_minimum(0), m_maximum(std::numeric_limits<std::size_t>::max())+      {}++      /***+      * Creates a new name constraint.+      * @param base name+      * @param min minimum path length+      * @param max maximum path length+      */+      GeneralSubtree(const GeneralName& base, size_t min, size_t max)+      : m_base(base), m_minimum(min), m_maximum(max)+      {}++      /**+      * Creates a new name constraint for its string format.+      * @param str name constraint+      */+      GeneralSubtree(const std::string& str);++      void encode_into(DER_Encoder&) const override;++      void decode_from(BER_Decoder&) override;++      /**+      * @return name+      */+      const GeneralName& base() const { return m_base; }++      /**+      * @return minimum path length+      */+      size_t minimum() const { return m_minimum; }++      /**+      * @return maximum path length+      */+      size_t maximum() const { return m_maximum; }++   private:+      GeneralName m_base;+      size_t m_minimum;+      size_t m_maximum;+   };++std::ostream& operator<<(std::ostream& os, const GeneralSubtree& gs);++/**+* @brief Name Constraints+*+* Wraps the Name Constraints associated with a certificate.+*/+class BOTAN_PUBLIC_API(2,0) NameConstraints final+   {+   public:+      /**+      * Creates an empty name NameConstraints.+      */+      NameConstraints() : m_permitted_subtrees(), m_excluded_subtrees() {}++      /**+      * Creates NameConstraints from a list of permitted and excluded subtrees.+      * @param permitted_subtrees names for which the certificate is permitted+      * @param excluded_subtrees names for which the certificate is not permitted+      */+      NameConstraints(std::vector<GeneralSubtree>&& permitted_subtrees,+                    std::vector<GeneralSubtree>&& excluded_subtrees)+      : m_permitted_subtrees(permitted_subtrees), m_excluded_subtrees(excluded_subtrees)+      {}++      /**+      * @return permitted names+      */+      const std::vector<GeneralSubtree>& permitted() const { return m_permitted_subtrees; }++      /**+      * @return excluded names+      */+      const std::vector<GeneralSubtree>& excluded() const { return m_excluded_subtrees; }++   private:+      std::vector<GeneralSubtree> m_permitted_subtrees;+      std::vector<GeneralSubtree> m_excluded_subtrees;+   };++/**+* X.509 Certificate Extension+*/+class BOTAN_PUBLIC_API(2,0) Certificate_Extension+   {+   public:+      /**+      * @return OID representing this extension+      */+      virtual OID oid_of() const = 0;++      /*+      * @return specific OID name+      * If possible OIDS table should match oid_name to OIDS, ie+      * OID::from_string(ext->oid_name()) == ext->oid_of()+      * Should return empty string if OID is not known+      */+      virtual std::string oid_name() const = 0;++      /**+      * Make a copy of this extension+      * @return copy of this+      */+      virtual Certificate_Extension* copy() const = 0;++      /*+      * Add the contents of this extension into the information+      * for the subject and/or issuer, as necessary.+      * @param subject the subject info+      * @param issuer the issuer info+      */+      virtual void contents_to(Data_Store& subject,+                               Data_Store& issuer) const = 0;++      /*+      * Callback visited during path validation.+      *+      * An extension can implement this callback to inspect+      * the path during path validation.+      *+      * If an error occurs during validation of this extension,+      * an appropriate status code shall be added to cert_status.+      *+      * @param subject Subject certificate that contains this extension+      * @param issuer Issuer certificate+      * @param status Certificate validation status codes for subject certificate+      * @param cert_path Certificate path which is currently validated+      * @param pos Position of subject certificate in cert_path+      */+      virtual void validate(const X509_Certificate& subject, const X509_Certificate& issuer,+            const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path,+            std::vector<std::set<Certificate_Status_Code>>& cert_status,+            size_t pos);++      virtual ~Certificate_Extension() = default;+   protected:+      friend class Extensions;+      virtual bool should_encode() const { return true; }+      virtual std::vector<uint8_t> encode_inner() const = 0;+      virtual void decode_inner(const std::vector<uint8_t>&) = 0;+   };++/**+* X.509 Certificate Extension List+*/+class BOTAN_PUBLIC_API(2,0) Extensions final : public ASN1_Object+   {+   public:+      /**+      * Look up an object in the extensions, based on OID Returns+      * nullptr if not set, if the extension was either absent or not+      * handled. The pointer returned is owned by the Extensions+      * object.+      * This would be better with an optional<T> return value+      */+      const Certificate_Extension* get_extension_object(const OID& oid) const;++      template<typename T>+      const T* get_extension_object_as(const OID& oid = T::static_oid()) const+         {+         if(const Certificate_Extension* extn = get_extension_object(oid))+            {+            // Unknown_Extension oid_name is empty+            if(extn->oid_name().empty())+               {+               return nullptr;+               }+            else if(const T* extn_as_T = dynamic_cast<const T*>(extn))+               {+               return extn_as_T;+               }+            else+               {+               throw Decoding_Error("Exception::get_extension_object_as dynamic_cast failed");+               }+            }++         return nullptr;+         }++      /**+      * Return the set of extensions in the order they appeared in the certificate+      * (or as they were added, if constructed)+      */+      const std::vector<OID>& get_extension_oids() const+         {+         return m_extension_oids;+         }++      /**+      * Return true if an extension was set+      */+      bool extension_set(const OID& oid) const;++      /**+      * Return true if an extesion was set and marked critical+      */+      bool critical_extension_set(const OID& oid) const;++      /**+      * Return the raw bytes of the extension+      * Will throw if OID was not set as an extension.+      */+      std::vector<uint8_t> get_extension_bits(const OID& oid) const;++      void encode_into(class DER_Encoder&) const override;+      void decode_from(class BER_Decoder&) override;+      void contents_to(Data_Store&, Data_Store&) const;++      /**+      * Adds a new extension to the list.+      * @param extn pointer to the certificate extension (Extensions takes ownership)+      * @param critical whether this extension should be marked as critical+      * @throw Invalid_Argument if the extension is already present in the list+      */+      void add(Certificate_Extension* extn, bool critical = false);++      /**+      * Adds a new extension to the list unless it already exists. If the extension+      * already exists within the Extensions object, the extn pointer will be deleted.+      *+      * @param extn pointer to the certificate extension (Extensions takes ownership)+      * @param critical whether this extension should be marked as critical+      * @return true if the object was added false if the extension was already used+      */+      bool add_new(Certificate_Extension* extn, bool critical = false);++      /**+      * Adds an extension to the list or replaces it.+      * @param extn the certificate extension+      * @param critical whether this extension should be marked as critical+      */+      void replace(Certificate_Extension* extn, bool critical = false);++      /**+      * Remove an extension from the list. Returns true if the+      * extension had been set, false otherwise.+      */+      bool remove(const OID& oid);++      /**+      * Searches for an extension by OID and returns the result.+      * Only the known extensions types declared in this header+      * are searched for by this function.+      * @return Copy of extension with oid, nullptr if not found.+      * Can avoid creating a copy by using get_extension_object function+      */+      std::unique_ptr<Certificate_Extension> get(const OID& oid) const;++      /**+      * Searches for an extension by OID and returns the result decoding+      * it to some arbitrary extension type chosen by the application.+      *+      * Only the unknown extensions, that is, extensions types that+      * are not declared in this header, are searched for by this+      * function.+      *+      * @return Pointer to new extension with oid, nullptr if not found.+      */+      template<typename T>+      std::unique_ptr<T> get_raw(const OID& oid) const+         {+         auto extn_info = m_extension_info.find(oid);++         if(extn_info != m_extension_info.end())+            {+            // Unknown_Extension oid_name is empty+            if(extn_info->second.obj().oid_name() == "")+               {+               std::unique_ptr<T> ext(new T);+               ext->decode_inner(extn_info->second.bits());+               return ext;+               }+            }+         return nullptr;+         }++      /**+      * Returns a copy of the list of extensions together with the corresponding+      * criticality flag. All extensions are encoded as some object, falling back+      * to Unknown_Extension class which simply allows reading the bytes as well+      * as the criticality flag.+      */+      std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> extensions() const;++      /**+      * Returns the list of extensions as raw, encoded bytes+      * together with the corresponding criticality flag.+      * Contains all extensions, including any extensions encoded as Unknown_Extension+      */+      std::map<OID, std::pair<std::vector<uint8_t>, bool>> extensions_raw() const;++      Extensions() {}++      Extensions(const Extensions&) = default;+      Extensions& operator=(const Extensions&) = default;++      Extensions(Extensions&&) = default;+      Extensions& operator=(Extensions&&) = default;++   private:+      static std::unique_ptr<Certificate_Extension>+         create_extn_obj(const OID& oid,+                         bool critical,+                         const std::vector<uint8_t>& body);++      class Extensions_Info+         {+         public:+            Extensions_Info(bool critical,+                            Certificate_Extension* ext) :+               m_obj(ext),+               m_bits(m_obj->encode_inner()),+               m_critical(critical)+               {+               }++            Extensions_Info(bool critical,+                            const std::vector<uint8_t>& encoding,+                            Certificate_Extension* ext) :+               m_obj(ext),+               m_bits(encoding),+               m_critical(critical)+               {+               }++            bool is_critical() const { return m_critical; }+            const std::vector<uint8_t>& bits() const { return m_bits; }+            const Certificate_Extension& obj() const+               {+               BOTAN_ASSERT_NONNULL(m_obj.get());+               return *m_obj.get();+               }++         private:+            std::shared_ptr<Certificate_Extension> m_obj;+            std::vector<uint8_t> m_bits;+            bool m_critical = false;+         };++      std::vector<OID> m_extension_oids;+      std::map<OID, Extensions_Info> m_extension_info;+   };++}++#endif
+ third_party/botan/src/lib/x509/x509_attribute.cpp view
@@ -0,0 +1,58 @@+/*+* Attribute+* (C) 1999-2007 Jack Lloyd+*+* Botan is released under the Simplified BSD License (see license.txt)+*/++#include <botan/pkix_types.h>+#include <botan/der_enc.h>+#include <botan/ber_dec.h>+#include <botan/oids.h>++namespace Botan {++/*+* Create an Attribute+*/+Attribute::Attribute(const OID& attr_oid, const std::vector<uint8_t>& attr_value) :+   oid(attr_oid),+   parameters(attr_value)+   {}++/*+* Create an Attribute+*/+Attribute::Attribute(const std::string& attr_oid,+                     const std::vector<uint8_t>& attr_value) :+   oid(OID::from_string(attr_oid)),+   parameters(attr_value)+   {}++/*+* DER encode a Attribute+*/+void Attribute::encode_into(DER_Encoder& codec) const+   {+   codec.start_cons(SEQUENCE)+      .encode(oid)+      .start_cons(SET)+         .raw_bytes(parameters)+      .end_cons()+   .end_cons();+   }++/*+* Decode a BER encoded Attribute+*/+void Attribute::decode_from(BER_Decoder& codec)+   {+   codec.start_cons(SEQUENCE)+      .decode(oid)+      .start_cons(SET)+         .raw_bytes(parameters)+      .end_cons()+   .end_cons();+   }++}
third_party/botan/src/lib/x509/x509_ca.cpp view
@@ -6,20 +6,20 @@ */  #include <botan/x509_ca.h>+#include <botan/x509_key.h> #include <botan/x509self.h>-#include <botan/pkcs10.h>+#include <botan/x509_ext.h>+#include <botan/pkix_types.h> #include <botan/pubkey.h> #include <botan/der_enc.h> #include <botan/bigint.h> #include <botan/parsing.h> #include <botan/oids.h> #include <botan/hash.h>-#include <botan/key_constraint.h> #include <botan/emsa.h> #include <botan/scan_name.h> #include <algorithm> #include <iterator>-#include <map>  namespace Botan { 
third_party/botan/src/lib/x509/x509_ca.h view
@@ -11,6 +11,7 @@ #include <botan/x509cert.h> #include <botan/x509_crl.h> #include <chrono>+#include <map>  #if defined(BOTAN_HAS_SYSTEM_RNG)   #include <botan/system_rng.h>
third_party/botan/src/lib/x509/x509_crl.h view
@@ -9,16 +9,81 @@ #define BOTAN_X509_CRL_H_  #include <botan/x509_obj.h>-#include <botan/x509_dn.h>-#include <botan/crl_ent.h>+#include <botan/asn1_obj.h>+#include <botan/pkix_enums.h> #include <vector>  namespace Botan {  class Extensions; class X509_Certificate;+class X509_DN; +struct CRL_Entry_Data; struct CRL_Data;++/**+* This class represents CRL entries+*/+class BOTAN_PUBLIC_API(2,0) CRL_Entry final : public ASN1_Object+   {+   public:+      void encode_into(class DER_Encoder&) const override;+      void decode_from(class BER_Decoder&) override;++      /**+      * Get the serial number of the certificate associated with this entry.+      * @return certificate's serial number+      */+      const std::vector<uint8_t>& serial_number() const;++      /**+      * Get the revocation date of the certificate associated with this entry+      * @return certificate's revocation date+      */+      const X509_Time& expire_time() const;++      /**+      * Get the entries reason code+      * @return reason code+      */+      CRL_Code reason_code() const;++      /**+      * Get the extensions on this CRL entry+      */+      const Extensions& extensions() const;++      /**+      * Create uninitialized CRL_Entry object+      */+      CRL_Entry() = default;++      /**+      * Construct an CRL entry.+      * @param cert the certificate to revoke+      * @param reason the reason code to set in the entry+      */+      CRL_Entry(const X509_Certificate& cert,+                CRL_Code reason = UNSPECIFIED);++   private:+      friend class X509_CRL;++      const CRL_Entry_Data& data() const;++      std::shared_ptr<CRL_Entry_Data> m_data;+   };++/**+* Test two CRL entries for equality in all fields.+*/+BOTAN_PUBLIC_API(2,0) bool operator==(const CRL_Entry&, const CRL_Entry&);++/**+* Test two CRL entries for inequality in at least one field.+*/+BOTAN_PUBLIC_API(2,0) bool operator!=(const CRL_Entry&, const CRL_Entry&);  /** * This class represents X.509 Certificate Revocation Lists (CRLs).
third_party/botan/src/lib/x509/x509_dn.cpp view
@@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/x509_dn.h>+#include <botan/pkix_types.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/parsing.h>@@ -291,7 +291,7 @@          rdn.start_cons(SEQUENCE)             .decode(oid)             .decode(str) // TODO support Any-            .end_cons().verify_end("Invalid X509_DN, data follows RDN");+            .end_cons();           add_attribute(oid, str);          }
third_party/botan/src/lib/x509/x509_dn.h view
@@ -1,104 +1,11 @@ /*-* X.509 Distinguished Name-* (C) 1999-2010,2018 Jack Lloyd-* (C) 2017 Fabian Weissberg, Rohde & Schwarz Cybersecurity-* * Botan is released under the Simplified BSD License (see license.txt) */  #ifndef BOTAN_X509_DN_H_ #define BOTAN_X509_DN_H_ -#include <botan/asn1_obj.h>-#include <botan/asn1_oid.h>-#include <botan/asn1_str.h>-#include <vector>-#include <map>-#include <iosfwd>--namespace Botan {--/**-* Distinguished Name-*/-class BOTAN_PUBLIC_API(2,0) X509_DN final : public ASN1_Object-   {-   public:-      X509_DN() = default;--      explicit X509_DN(const std::multimap<OID, std::string>& args)-         {-         for(auto i : args)-            add_attribute(i.first, i.second);-         }--      explicit X509_DN(const std::multimap<std::string, std::string>& args)-         {-         for(auto i : args)-            add_attribute(i.first, i.second);-         }--      void encode_into(class DER_Encoder&) const override;-      void decode_from(class BER_Decoder&) override;--      bool has_field(const OID& oid) const;-      ASN1_String get_first_attribute(const OID& oid) const;--      /*-      * Return the BER encoded data, if any-      */-      const std::vector<uint8_t>& get_bits() const { return m_dn_bits; }--      bool empty() const { return m_rdn.empty(); }--      std::string to_string() const;--      const std::vector<std::pair<OID,ASN1_String>>& dn_info() const { return m_rdn; }--      std::multimap<OID, std::string> get_attributes() const;-      std::multimap<std::string, std::string> contents() const;--      bool has_field(const std::string& attr) const;-      std::vector<std::string> get_attribute(const std::string& attr) const;-      std::string get_first_attribute(const std::string& attr) const;--      void add_attribute(const std::string& key, const std::string& val);--      void add_attribute(const OID& oid, const std::string& val)-         {-         add_attribute(oid, ASN1_String(val));-         }--      void add_attribute(const OID& oid, const ASN1_String& val);--      static std::string deref_info_field(const std::string& key);--      /**-      * Lookup upper bounds in characters for the length of distinguished name fields-      * as given in RFC 5280, Appendix A.-      *-      * @param oid the oid of the DN to lookup-      * @return the upper bound, or zero if no ub is known to Botan-      */-      static size_t lookup_ub(const OID& oid);--   private:-      std::vector<std::pair<OID,ASN1_String>> m_rdn;-      std::vector<uint8_t> m_dn_bits;-   };--bool BOTAN_PUBLIC_API(2,0) operator==(const X509_DN& dn1, const X509_DN& dn2);-bool BOTAN_PUBLIC_API(2,0) operator!=(const X509_DN& dn1, const X509_DN& dn2);--/*-The ordering here is arbitrary and may change from release to release.-It is intended for allowing DNs as keys in std::map and similiar containers-*/-bool BOTAN_PUBLIC_API(2,0) operator<(const X509_DN& dn1, const X509_DN& dn2);--BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream& out, const X509_DN& dn);-BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream& in, X509_DN& dn);--}+#include <botan/pkix_types.h>+BOTAN_DEPRECATED_HEADER(x509_dn.h)  #endif
third_party/botan/src/lib/x509/x509_dn_ub.cpp view
@@ -9,8 +9,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/x509_dn.h>-#include <botan/asn1_oid.h>+#include <botan/pkix_types.h>+#include <botan/asn1_obj.h> #include <map>  namespace {
third_party/botan/src/lib/x509/x509_ext.cpp view
@@ -657,20 +657,17 @@    {    if(!m_name_constraints.permitted().empty() || !m_name_constraints.excluded().empty())       {-      if(!subject.is_CA_cert() || !subject.is_critical("X509v3.NameConstraints"))+      if(!subject.is_CA_cert())+         {          cert_status.at(pos).insert(Certificate_Status_Code::NAME_CONSTRAINT_ERROR);+         }        const bool issuer_name_constraint_critical =          issuer.is_critical("X509v3.NameConstraints"); -      const bool at_self_signed_root = (pos == cert_path.size() - 1);-       // Check that all subordinate certs pass the name constraint-      for(size_t j = 0; j <= pos; ++j)+      for(size_t j = 0; j < pos; ++j)          {-         if(pos == j && at_self_signed_root)-            continue;-          bool permitted = m_name_constraints.permitted().empty();          bool failed = false; 
third_party/botan/src/lib/x509/x509_ext.h view
@@ -8,283 +8,13 @@ #ifndef BOTAN_X509_EXTENSIONS_H_ #define BOTAN_X509_EXTENSIONS_H_ -#include <botan/asn1_obj.h>-#include <botan/asn1_oid.h>-#include <botan/asn1_alt_name.h>-#include <botan/cert_status.h>-#include <botan/name_constraint.h>-#include <botan/key_constraint.h>-#include <botan/crl_ent.h>+#include <botan/pkix_types.h> #include <set>  namespace Botan {  class Data_Store; class X509_Certificate;--/**-* X.509 Certificate Extension-*/-class BOTAN_PUBLIC_API(2,0) Certificate_Extension-   {-   public:-      /**-      * @return OID representing this extension-      */-      virtual OID oid_of() const = 0;--      /*-      * @return specific OID name-      * If possible OIDS table should match oid_name to OIDS, ie-      * OID::from_string(ext->oid_name()) == ext->oid_of()-      * Should return empty string if OID is not known-      */-      virtual std::string oid_name() const = 0;--      /**-      * Make a copy of this extension-      * @return copy of this-      */-      virtual Certificate_Extension* copy() const = 0;--      /*-      * Add the contents of this extension into the information-      * for the subject and/or issuer, as necessary.-      * @param subject the subject info-      * @param issuer the issuer info-      */-      virtual void contents_to(Data_Store& subject,-                               Data_Store& issuer) const = 0;--      /*-      * Callback visited during path validation.-      *-      * An extension can implement this callback to inspect-      * the path during path validation.-      *-      * If an error occurs during validation of this extension,-      * an appropriate status code shall be added to cert_status.-      *-      * @param subject Subject certificate that contains this extension-      * @param issuer Issuer certificate-      * @param status Certificate validation status codes for subject certificate-      * @param cert_path Certificate path which is currently validated-      * @param pos Position of subject certificate in cert_path-      */-      virtual void validate(const X509_Certificate& subject, const X509_Certificate& issuer,-            const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path,-            std::vector<std::set<Certificate_Status_Code>>& cert_status,-            size_t pos);--      virtual ~Certificate_Extension() = default;-   protected:-      friend class Extensions;-      virtual bool should_encode() const { return true; }-      virtual std::vector<uint8_t> encode_inner() const = 0;-      virtual void decode_inner(const std::vector<uint8_t>&) = 0;-   };--/**-* X.509 Certificate Extension List-*/-class BOTAN_PUBLIC_API(2,0) Extensions final : public ASN1_Object-   {-   public:-      /**-      * Look up an object in the extensions, based on OID Returns-      * nullptr if not set, if the extension was either absent or not-      * handled. The pointer returned is owned by the Extensions-      * object.-      * This would be better with an optional<T> return value-      */-      const Certificate_Extension* get_extension_object(const OID& oid) const;--      template<typename T>-      const T* get_extension_object_as(const OID& oid = T::static_oid()) const-         {-         if(const Certificate_Extension* extn = get_extension_object(oid))-            {-            // Unknown_Extension oid_name is empty-            if(extn->oid_name().empty())-               {-               return nullptr;-               }-            else if(const T* extn_as_T = dynamic_cast<const T*>(extn))-               {-               return extn_as_T;-               }-            else-               {-               throw Decoding_Error("Exception::get_extension_object_as dynamic_cast failed");-               }-            }--         return nullptr;-         }--      /**-      * Return the set of extensions in the order they appeared in the certificate-      * (or as they were added, if constructed)-      */-      const std::vector<OID>& get_extension_oids() const-         {-         return m_extension_oids;-         }--      /**-      * Return true if an extension was set-      */-      bool extension_set(const OID& oid) const;--      /**-      * Return true if an extesion was set and marked critical-      */-      bool critical_extension_set(const OID& oid) const;--      /**-      * Return the raw bytes of the extension-      * Will throw if OID was not set as an extension.-      */-      std::vector<uint8_t> get_extension_bits(const OID& oid) const;--      void encode_into(class DER_Encoder&) const override;-      void decode_from(class BER_Decoder&) override;-      void contents_to(Data_Store&, Data_Store&) const;--      /**-      * Adds a new extension to the list.-      * @param extn pointer to the certificate extension (Extensions takes ownership)-      * @param critical whether this extension should be marked as critical-      * @throw Invalid_Argument if the extension is already present in the list-      */-      void add(Certificate_Extension* extn, bool critical = false);--      /**-      * Adds a new extension to the list unless it already exists. If the extension-      * already exists within the Extensions object, the extn pointer will be deleted.-      *-      * @param extn pointer to the certificate extension (Extensions takes ownership)-      * @param critical whether this extension should be marked as critical-      * @return true if the object was added false if the extension was already used-      */-      bool add_new(Certificate_Extension* extn, bool critical = false);--      /**-      * Adds an extension to the list or replaces it.-      * @param extn the certificate extension-      * @param critical whether this extension should be marked as critical-      */-      void replace(Certificate_Extension* extn, bool critical = false);--      /**-      * Remove an extension from the list. Returns true if the-      * extension had been set, false otherwise.-      */-      bool remove(const OID& oid);--      /**-      * Searches for an extension by OID and returns the result.-      * Only the known extensions types declared in this header-      * are searched for by this function.-      * @return Copy of extension with oid, nullptr if not found.-      * Can avoid creating a copy by using get_extension_object function-      */-      std::unique_ptr<Certificate_Extension> get(const OID& oid) const;--      /**-      * Searches for an extension by OID and returns the result decoding-      * it to some arbitrary extension type chosen by the application.-      *-      * Only the unknown extensions, that is, extensions types that-      * are not declared in this header, are searched for by this-      * function.-      *-      * @return Pointer to new extension with oid, nullptr if not found.-      */-      template<typename T>-      std::unique_ptr<T> get_raw(const OID& oid) const-         {-         auto extn_info = m_extension_info.find(oid);--         if(extn_info != m_extension_info.end())-            {-            // Unknown_Extension oid_name is empty-            if(extn_info->second.obj().oid_name() == "")-               {-               std::unique_ptr<T> ext(new T);-               ext->decode_inner(extn_info->second.bits());-               return ext;-               }-            }-         return nullptr;-         }--      /**-      * Returns a copy of the list of extensions together with the corresponding-      * criticality flag. All extensions are encoded as some object, falling back-      * to Unknown_Extension class which simply allows reading the bytes as well-      * as the criticality flag.-      */-      std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> extensions() const;--      /**-      * Returns the list of extensions as raw, encoded bytes-      * together with the corresponding criticality flag.-      * Contains all extensions, including any extensions encoded as Unknown_Extension-      */-      std::map<OID, std::pair<std::vector<uint8_t>, bool>> extensions_raw() const;--      Extensions() {}--      Extensions(const Extensions&) = default;-      Extensions& operator=(const Extensions&) = default;--      Extensions(Extensions&&) = default;-      Extensions& operator=(Extensions&&) = default;--   private:-      static std::unique_ptr<Certificate_Extension>-         create_extn_obj(const OID& oid,-                         bool critical,-                         const std::vector<uint8_t>& body);--      class Extensions_Info-         {-         public:-            Extensions_Info(bool critical,-                            Certificate_Extension* ext) :-               m_obj(ext),-               m_bits(m_obj->encode_inner()),-               m_critical(critical)-               {-               }--            Extensions_Info(bool critical,-                            const std::vector<uint8_t>& encoding,-                            Certificate_Extension* ext) :-               m_obj(ext),-               m_bits(encoding),-               m_critical(critical)-               {-               }--            bool is_critical() const { return m_critical; }-            const std::vector<uint8_t>& bits() const { return m_bits; }-            const Certificate_Extension& obj() const-               {-               BOTAN_ASSERT_NONNULL(m_obj.get());-               return *m_obj.get();-               }--         private:-            std::shared_ptr<Certificate_Extension> m_obj;-            std::vector<uint8_t> m_bits;-            bool m_critical = false;-         };--      std::vector<OID> m_extension_oids;-      std::map<OID, Extensions_Info> m_extension_info;-   };  namespace Cert_Extension { 
third_party/botan/src/lib/x509/x509_obj.h view
@@ -9,8 +9,7 @@ #define BOTAN_X509_OBJECT_H_  #include <botan/asn1_obj.h>-#include <botan/alg_id.h>-#include <botan/cert_status.h>+#include <botan/pkix_enums.h> #include <vector>  namespace Botan {
third_party/botan/src/lib/x509/x509cert.cpp view
@@ -7,6 +7,7 @@ */  #include <botan/x509cert.h>+#include <botan/x509_key.h> #include <botan/datastor.h> #include <botan/pk_keys.h> #include <botan/x509_ext.h>@@ -708,6 +709,11 @@       {       throw Decoding_Error("X509_Certificate::load_subject_public_key", e);       }+   }++Public_Key* X509_Certificate::subject_public_key() const+   {+   return load_subject_public_key().release();    }  std::vector<uint8_t> X509_Certificate::raw_issuer_dn_sha256() const
third_party/botan/src/lib/x509/x509cert.h view
@@ -9,18 +9,15 @@ #define BOTAN_X509_CERTS_H_  #include <botan/x509_obj.h>-#include <botan/x509_key.h>-#include <botan/asn1_time.h>-#include <botan/key_constraint.h>-#include <botan/name_constraint.h> #include <memory>  namespace Botan {  class Public_Key; class X509_DN;-class AlternativeName; class Extensions;+class AlternativeName;+class NameConstraints;  enum class Usage_Type    {@@ -45,12 +42,11 @@       * with the subject of this certificate. This object is owned       * by the caller.       *+      * Prefer load_subject_public_key in new code+      *       * @return public key       */-      Public_Key* subject_public_key() const-         {-         return load_subject_public_key().release();-         }+      Public_Key* subject_public_key() const;        /**       * Create a public key object associated with the public key bits in this
third_party/botan/src/lib/x509/x509path.h view
@@ -8,7 +8,7 @@ #ifndef BOTAN_X509_CERT_PATH_VALIDATION_H_ #define BOTAN_X509_CERT_PATH_VALIDATION_H_ -#include <botan/cert_status.h>+#include <botan/pkix_enums.h> #include <botan/x509cert.h> #include <botan/certstor.h> #include <botan/ocsp.h>
third_party/botan/src/lib/x509/x509self.cpp view
@@ -6,6 +6,7 @@ */  #include <botan/x509self.h>+#include <botan/x509_key.h> #include <botan/x509_ext.h> #include <botan/x509_ca.h> #include <botan/der_enc.h>
third_party/botan/src/lib/x509/x509self.h view
@@ -9,9 +9,8 @@ #define BOTAN_X509_SELF_H_  #include <botan/x509cert.h>-#include <botan/x509_ext.h> #include <botan/pkcs10.h>-#include <botan/asn1_time.h>+#include <botan/pkix_types.h>  namespace Botan { 
third_party/botan/src/tests/data/x509/bsi/expected.txt view
@@ -48,7 +48,7 @@ cert_path_ext_13$Unknown critical extension encountered cert_path_ext_14$Unknown critical extension encountered cert_path_ext_15$Certificate does not pass name constraint-cert_path_ext_16$Certificate does not pass name constraint+cert_path_ext_16$Verified #cert_path_ext_17$ cert_path_ext_18$Unknown critical extension encountered cert_path_ext_19$Unknown critical extension encountered
third_party/botan/src/tests/test_aead.cpp view
@@ -459,7 +459,7 @@          }    }; -BOTAN_REGISTER_TEST("aead", AEAD_Tests);+BOTAN_REGISTER_TEST("modes", "aead", AEAD_Tests);  #endif 
third_party/botan/src/tests/test_asn1.cpp view
@@ -9,9 +9,7 @@ #if defined(BOTAN_HAS_ASN1)    #include <botan/der_enc.h>    #include <botan/ber_dec.h>-   #include <botan/asn1_str.h>    #include <botan/asn1_print.h>-   #include <botan/asn1_time.h> #endif  namespace Botan_Tests {@@ -289,7 +287,7 @@          }    }; -BOTAN_REGISTER_TEST("asn1", ASN1_Tests);+BOTAN_REGISTER_TEST("asn1", "asn1", ASN1_Tests);  class ASN1_Time_Parsing_Tests final : public Text_Based_Test    {@@ -332,7 +330,7 @@          }    }; -BOTAN_REGISTER_TEST("asn1_time", ASN1_Time_Parsing_Tests);+BOTAN_REGISTER_TEST("asn1", "asn1_time", ASN1_Time_Parsing_Tests);  class ASN1_Printer_Tests final : public Test    {@@ -358,7 +356,7 @@          }    }; -BOTAN_REGISTER_TEST("asn1_printer", ASN1_Printer_Tests);+BOTAN_REGISTER_TEST("asn1", "asn1_printer", ASN1_Printer_Tests);  #endif 
third_party/botan/src/tests/test_bigint.cpp view
@@ -217,8 +217,52 @@          }    }; -BOTAN_REGISTER_TEST("bigint_unit", BigInt_Unit_Tests);+BOTAN_REGISTER_TEST("math", "bigint_unit", BigInt_Unit_Tests); +class BigInt_Cmp_Test final : public Text_Based_Test+   {+   public:+      BigInt_Cmp_Test() : Text_Based_Test("bn/cmp.vec", "X,Y,R") {}++      Test::Result run_one_test(const std::string& op, const VarMap& vars) override+         {+         Test::Result result("BigInt Comparison " + op);++         const BigInt x = vars.get_req_bn("X");+         const BigInt y = vars.get_req_bn("Y");+         const bool expected = vars.get_req_bool("R");++         if(op == "EQ")+            {+            result.confirm("Values equal", x == y, expected);+            }+         else if(op == "LT")+            {+            result.confirm("Values LT", x < y, expected);++            if(expected)+               result.confirm("If LT then reverse is GT", y >= x);+            else+               result.confirm("If not LT then GTE", x >= y);+            }+         else if(op == "LTE")+            {+            result.confirm("Values LTE", x <= y, expected);++            if(expected)+               result.confirm("If LTE then either LT or EQ", x < y || x == y);+            else+               result.confirm("If not LTE then GT", x > y);+            }+         else+            throw Test_Error("Unknown BigInt comparison type " + op);++         return result;+         }+   };++BOTAN_REGISTER_TEST("math", "bn_cmp", BigInt_Cmp_Test);+ class BigInt_Add_Test final : public Text_Based_Test    {    public:@@ -250,7 +294,7 @@     }; -BOTAN_REGISTER_TEST("bn_add", BigInt_Add_Test);+BOTAN_REGISTER_TEST("math", "bn_add", BigInt_Add_Test);  class BigInt_Sub_Test final : public Text_Based_Test    {@@ -275,7 +319,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_sub", BigInt_Sub_Test);+BOTAN_REGISTER_TEST("math", "bn_sub", BigInt_Sub_Test);  class BigInt_Mul_Test final : public Text_Based_Test    {@@ -305,7 +349,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_mul", BigInt_Mul_Test);+BOTAN_REGISTER_TEST("math", "bn_mul", BigInt_Mul_Test);  class BigInt_Sqr_Test final : public Text_Based_Test    {@@ -326,7 +370,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_sqr", BigInt_Sqr_Test);+BOTAN_REGISTER_TEST("math", "bn_sqr", BigInt_Sqr_Test);  class BigInt_Div_Test final : public Text_Based_Test    {@@ -365,7 +409,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_div", BigInt_Div_Test);+BOTAN_REGISTER_TEST("math", "bn_div", BigInt_Div_Test);  class BigInt_Mod_Test final : public Text_Based_Test    {@@ -417,7 +461,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_mod", BigInt_Mod_Test);+BOTAN_REGISTER_TEST("math", "bn_mod", BigInt_Mod_Test);  class BigInt_GCD_Test final : public Text_Based_Test    {@@ -440,7 +484,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_gcd", BigInt_GCD_Test);+BOTAN_REGISTER_TEST("math", "bn_gcd", BigInt_GCD_Test);  class BigInt_Jacobi_Test final : public Text_Based_Test    {@@ -468,7 +512,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_jacobi", BigInt_Jacobi_Test);+BOTAN_REGISTER_TEST("math", "bn_jacobi", BigInt_Jacobi_Test);  class BigInt_Lshift_Test final : public Text_Based_Test    {@@ -493,7 +537,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_lshift", BigInt_Lshift_Test);+BOTAN_REGISTER_TEST("math", "bn_lshift", BigInt_Lshift_Test);  class BigInt_Rshift_Test final : public Text_Based_Test    {@@ -518,7 +562,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_rshift", BigInt_Rshift_Test);+BOTAN_REGISTER_TEST("math", "bn_rshift", BigInt_Rshift_Test);  class BigInt_Powmod_Test final : public Text_Based_Test    {@@ -571,7 +615,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_powmod", BigInt_Powmod_Test);+BOTAN_REGISTER_TEST("math", "bn_powmod", BigInt_Powmod_Test);  class BigInt_IsPrime_Test final : public Text_Based_Test    {@@ -595,7 +639,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_isprime", BigInt_IsPrime_Test);+BOTAN_REGISTER_TEST("math", "bn_isprime", BigInt_IsPrime_Test);  class BigInt_IsSquare_Test final : public Text_Based_Test    {@@ -614,7 +658,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_issquare", BigInt_IsSquare_Test);+BOTAN_REGISTER_TEST("math", "bn_issquare", BigInt_IsSquare_Test);  class BigInt_Ressol_Test final : public Text_Based_Test    {@@ -643,7 +687,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_ressol", BigInt_Ressol_Test);+BOTAN_REGISTER_TEST("math", "bn_ressol", BigInt_Ressol_Test);  class BigInt_InvMod_Test final : public Text_Based_Test    {@@ -684,7 +728,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_invmod", BigInt_InvMod_Test);+BOTAN_REGISTER_TEST("math", "bn_invmod", BigInt_InvMod_Test);  class BigInt_Rand_Test final : public Text_Based_Test    {@@ -709,7 +753,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_rand", BigInt_Rand_Test);+BOTAN_REGISTER_TEST("math", "bn_rand", BigInt_Rand_Test);  class Lucas_Primality_Test final : public Test    {@@ -750,7 +794,7 @@          }    }; -BOTAN_REGISTER_TEST("bn_lucas", Lucas_Primality_Test);+BOTAN_REGISTER_TEST("math", "bn_lucas", Lucas_Primality_Test);  class DSA_ParamGen_Test final : public Text_Based_Test    {@@ -798,7 +842,7 @@          }    }; -BOTAN_REGISTER_TEST("dsa_param", DSA_ParamGen_Test);+BOTAN_REGISTER_TEST("math", "dsa_param", DSA_ParamGen_Test);  #endif 
third_party/botan/src/tests/test_block.cpp view
@@ -196,7 +196,7 @@     }; -BOTAN_REGISTER_TEST("block", Block_Cipher_Tests);+BOTAN_REGISTER_TEST("block", "block", Block_Cipher_Tests);  } 
third_party/botan/src/tests/test_blowfish.cpp view
@@ -39,7 +39,7 @@          }    }; -BOTAN_REGISTER_TEST("blowfish_salted", Blowfish_Salted_Tests);+BOTAN_REGISTER_TEST("block", "blowfish_salted", Blowfish_Salted_Tests);  } 
third_party/botan/src/tests/test_c25519.cpp view
@@ -39,7 +39,7 @@          return result;          }    };-BOTAN_REGISTER_TEST("curve25519_scalar", Curve25519_Sclarmult_Tests);+BOTAN_REGISTER_TEST("pubkey", "curve25519_scalar", Curve25519_Sclarmult_Tests);  class Curve25519_Agreement_Tests final : public PK_Key_Agreement_Test    {@@ -67,7 +67,7 @@          return vars.get_req_bin("CounterKey");          }    };-BOTAN_REGISTER_TEST("curve25519_agreement", Curve25519_Agreement_Tests);+BOTAN_REGISTER_TEST("pubkey", "curve25519_agreement", Curve25519_Agreement_Tests);  class Curve25519_Roundtrip_Test final : public Test    {@@ -150,7 +150,7 @@          }    }; -BOTAN_REGISTER_TEST("curve25519_rt", Curve25519_Roundtrip_Test);+BOTAN_REGISTER_TEST("pubkey", "curve25519_rt", Curve25519_Roundtrip_Test);  class Curve25519_Keygen_Tests final : public PK_Key_Generation_Test    {@@ -165,7 +165,7 @@          }    }; -BOTAN_REGISTER_TEST("curve25519_keygen", Curve25519_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "curve25519_keygen", Curve25519_Keygen_Tests);  #endif 
third_party/botan/src/tests/test_certstor.cpp view
@@ -10,6 +10,7 @@ #if defined(BOTAN_HAS_X509_CERTIFICATES)    #include <botan/x509cert.h>    #include <botan/certstor.h>+   #include <botan/pkix_types.h>    #include <botan/internal/filesystem.h>    #include <botan/pkcs8.h>    #include <botan/pk_keys.h>@@ -427,7 +428,7 @@          }    }; -BOTAN_REGISTER_TEST("certstor", Certstor_Tests);+BOTAN_REGISTER_TEST("x509", "certstor", Certstor_Tests); #endif } }
third_party/botan/src/tests/test_certstor_flatfile.cpp view
@@ -299,7 +299,7 @@          }    }; -BOTAN_REGISTER_TEST("certstor_flatfile", Certstor_Flatfile_Tests);+BOTAN_REGISTER_TEST("x509", "certstor_flatfile", Certstor_Flatfile_Tests);  } 
third_party/botan/src/tests/test_certstor_system.cpp view
@@ -345,7 +345,7 @@          }    }; -BOTAN_REGISTER_TEST("certstor_system", Certstor_System_Tests);+BOTAN_REGISTER_TEST("x509", "certstor_system", Certstor_System_Tests);  } 
third_party/botan/src/tests/test_certstor_utils.h view
@@ -15,7 +15,7 @@  #if defined(BOTAN_HAS_X509_CERTIFICATES) -#include <botan/x509_dn.h>+#include <botan/pkix_types.h>  namespace Botan_Tests { 
third_party/botan/src/tests/test_clang_bug.cpp view
@@ -108,7 +108,7 @@     }; -BOTAN_REGISTER_TEST("clang_bug", Clang_Bug_41810);+BOTAN_REGISTER_TEST("misc", "clang_bug", Clang_Bug_41810);  #endif // BOTAN_HAS_PUBLIC_KEY_CRYPTO 
third_party/botan/src/tests/test_compression.cpp view
@@ -171,7 +171,7 @@          }    }; -BOTAN_REGISTER_TEST("compression", Compression_Tests);+BOTAN_REGISTER_TEST("compression", "compression", Compression_Tests);  class CompressionCreate_Tests final : public Test    {@@ -229,7 +229,7 @@          }    }; -BOTAN_REGISTER_TEST("create_compression", CompressionCreate_Tests);+BOTAN_REGISTER_TEST("compression", "create_compression", CompressionCreate_Tests);  } 
third_party/botan/src/tests/test_cryptobox.cpp view
@@ -66,7 +66,7 @@     }; -BOTAN_REGISTER_TEST("cryptobox", Cryptobox_KAT);+BOTAN_REGISTER_TEST("misc", "cryptobox", Cryptobox_KAT);  #endif 
third_party/botan/src/tests/test_datastore.cpp view
@@ -64,7 +64,7 @@          }    }; -BOTAN_REGISTER_TEST("x509_datastore", Datastore_Tests);+BOTAN_REGISTER_TEST("x509", "x509_datastore", Datastore_Tests);  } 
third_party/botan/src/tests/test_dh.cpp view
@@ -149,10 +149,10 @@          }    }; -BOTAN_REGISTER_TEST("dh_kat", Diffie_Hellman_KAT_Tests);-BOTAN_REGISTER_TEST("dh_invalid", DH_Invalid_Key_Tests);+BOTAN_REGISTER_TEST("pubkey", "dh_kat", Diffie_Hellman_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "dh_invalid", DH_Invalid_Key_Tests); -BOTAN_REGISTER_TEST("dh_keygen", Diffie_Hellman_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "dh_keygen", Diffie_Hellman_Keygen_Tests);  #endif 
third_party/botan/src/tests/test_dl_group.cpp view
@@ -88,7 +88,7 @@          }    }; -BOTAN_REGISTER_TEST("dl_group", DL_Group_Tests);+BOTAN_REGISTER_TEST("pubkey", "dl_group", DL_Group_Tests);  class DL_Generate_Group_Tests final : public Test    {@@ -163,7 +163,7 @@          }    }; -BOTAN_REGISTER_TEST("dl_group_gen", DL_Generate_Group_Tests);+BOTAN_REGISTER_TEST("pubkey", "dl_group_gen", DL_Generate_Group_Tests);  class DL_Named_Group_Tests final : public Test    {@@ -238,7 +238,7 @@          }    }; -BOTAN_REGISTER_TEST("dl_group_named", DL_Named_Group_Tests);+BOTAN_REGISTER_TEST("pubkey", "dl_group_named", DL_Named_Group_Tests);  } 
third_party/botan/src/tests/test_dlies.cpp view
@@ -103,7 +103,7 @@          }    }; -BOTAN_REGISTER_TEST("dlies", DLIES_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "dlies", DLIES_KAT_Tests);  Test::Result test_xor()    {@@ -198,7 +198,7 @@          }    }; -BOTAN_REGISTER_TEST("dlies_unit", DLIES_Unit_Tests);+BOTAN_REGISTER_TEST("pubkey", "dlies_unit", DLIES_Unit_Tests);  #endif 
third_party/botan/src/tests/test_dsa.cpp view
@@ -100,9 +100,9 @@          }    }; -BOTAN_REGISTER_TEST("dsa_sign", DSA_KAT_Tests);-BOTAN_REGISTER_TEST("dsa_verify", DSA_Verification_Tests);-BOTAN_REGISTER_TEST("dsa_keygen", DSA_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "dsa_sign", DSA_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "dsa_verify", DSA_Verification_Tests);+BOTAN_REGISTER_TEST("pubkey", "dsa_keygen", DSA_Keygen_Tests);  #endif 
third_party/botan/src/tests/test_ecc_pointmul.cpp view
@@ -50,7 +50,7 @@          }    }; -BOTAN_REGISTER_TEST("ecc_basemul", ECC_Basepoint_Mul_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecc_basemul", ECC_Basepoint_Mul_Tests);  class ECC_Varpoint_Mul_Tests final : public Text_Based_Test    {@@ -88,7 +88,7 @@          }    }; -BOTAN_REGISTER_TEST("ecc_varmul", ECC_Varpoint_Mul_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecc_varmul", ECC_Varpoint_Mul_Tests);  #endif 
third_party/botan/src/tests/test_ecdh.cpp view
@@ -62,8 +62,8 @@    };  -BOTAN_REGISTER_TEST("ecdh_kat", ECDH_KAT_Tests);-BOTAN_REGISTER_TEST("ecdh_keygen", ECDH_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecdh_kat", ECDH_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecdh_keygen", ECDH_Keygen_Tests);  #endif 
third_party/botan/src/tests/test_ecdsa.cpp view
@@ -210,7 +210,7 @@          }    }; -BOTAN_REGISTER_TEST("ecdsa_key_recovery", ECDSA_Key_Recovery_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecdsa_key_recovery", ECDSA_Key_Recovery_Tests);  #endif @@ -255,12 +255,12 @@          }    }; -BOTAN_REGISTER_TEST("ecdsa_verify", ECDSA_Verification_Tests);-BOTAN_REGISTER_TEST("ecdsa_verify_wycheproof", ECDSA_Wycheproof_Verification_Tests);-BOTAN_REGISTER_TEST("ecdsa_sign", ECDSA_Signature_KAT_Tests);-BOTAN_REGISTER_TEST("ecdsa_sign_verify_der", ECDSA_Sign_Verify_DER_Test);-BOTAN_REGISTER_TEST("ecdsa_keygen", ECDSA_Keygen_Tests);-BOTAN_REGISTER_TEST("ecdsa_invalid", ECDSA_Invalid_Key_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecdsa_verify", ECDSA_Verification_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecdsa_verify_wycheproof", ECDSA_Wycheproof_Verification_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecdsa_sign", ECDSA_Signature_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecdsa_sign_verify_der", ECDSA_Sign_Verify_DER_Test);+BOTAN_REGISTER_TEST("pubkey", "ecdsa_keygen", ECDSA_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecdsa_invalid", ECDSA_Invalid_Key_Tests);  #endif 
third_party/botan/src/tests/test_ecgdsa.cpp view
@@ -68,8 +68,8 @@          }    }; -BOTAN_REGISTER_TEST("ecgdsa_sign", ECGDSA_Signature_KAT_Tests);-BOTAN_REGISTER_TEST("ecgdsa_keygen", ECGDSA_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecgdsa_sign", ECGDSA_Signature_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecgdsa_keygen", ECGDSA_Keygen_Tests);  #endif 
third_party/botan/src/tests/test_ecies.cpp view
@@ -186,7 +186,7 @@          }    }; -BOTAN_REGISTER_TEST("ecies_iso", ECIES_ISO_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecies_iso", ECIES_ISO_Tests);  #endif @@ -236,7 +236,7 @@     }; -BOTAN_REGISTER_TEST("ecies", ECIES_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecies", ECIES_Tests);  #if defined(BOTAN_HAS_KDF1_18033) && defined(BOTAN_HAS_HMAC) && defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_SHA2_64) @@ -438,7 +438,7 @@          }    }; -BOTAN_REGISTER_TEST("ecies_unit", ECIES_Unit_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecies_unit", ECIES_Unit_Tests);  #endif 
third_party/botan/src/tests/test_eckcdsa.cpp view
@@ -69,8 +69,8 @@          }    }; -BOTAN_REGISTER_TEST("eckcdsa_sign", ECKCDSA_Signature_KAT_Tests);-BOTAN_REGISTER_TEST("eckcdsa_keygen", ECKCDSA_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "eckcdsa_sign", ECKCDSA_Signature_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "eckcdsa_keygen", ECKCDSA_Keygen_Tests);  #endif 
third_party/botan/src/tests/test_ed25519.cpp view
@@ -111,9 +111,9 @@          }    }; -BOTAN_REGISTER_TEST("ed25519_verify", Ed25519_Verification_Tests);-BOTAN_REGISTER_TEST("ed25519_sign", Ed25519_Signature_Tests);-BOTAN_REGISTER_TEST("ed25519_curdle", Ed25519_Curdle_Format_Tests);+BOTAN_REGISTER_TEST("pubkey", "ed25519_verify", Ed25519_Verification_Tests);+BOTAN_REGISTER_TEST("pubkey", "ed25519_sign", Ed25519_Signature_Tests);+BOTAN_REGISTER_TEST("pubkey", "ed25519_curdle", Ed25519_Curdle_Format_Tests);  #endif 
third_party/botan/src/tests/test_elg.cpp view
@@ -53,8 +53,8 @@          }    }; -BOTAN_REGISTER_TEST("elgamal_encrypt", ElGamal_KAT_Tests);-BOTAN_REGISTER_TEST("elgamal_keygen", ElGamal_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "elgamal_encrypt", ElGamal_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "elgamal_keygen", ElGamal_Keygen_Tests);  #endif 
third_party/botan/src/tests/test_entropy.cpp view
@@ -128,7 +128,7 @@          }    }; -BOTAN_REGISTER_TEST("entropy", Entropy_Source_Tests);+BOTAN_REGISTER_TEST("rng", "entropy", Entropy_Source_Tests);  } 
third_party/botan/src/tests/test_ffi.cpp view
@@ -201,6 +201,7 @@          botan_rng_t system_rng;          botan_rng_t rdrand_rng = nullptr;          botan_rng_t null_rng;+         botan_rng_t custom_rng;           TEST_FFI_FAIL("invalid rng type", botan_rng_init, (&rng, "invalid_type")); @@ -247,6 +248,50 @@             TEST_FFI_OK(botan_rng_add_entropy, (rng, not_really_entropy, 32));             } +         size_t cb_counter = 0;++         auto custom_get_cb = [](void* context, uint8_t* out, size_t out_len) -> int+            {+            Botan::set_mem(out, out_len, 0x12);+            BOTAN_UNUSED(out, out_len);+            (*(static_cast<size_t*>(context)))++;+            return 0;+            };++         auto custom_add_entropy_cb = [](void* context, const uint8_t input[], size_t length) -> int+            {+            BOTAN_UNUSED(input, length);+            (*(static_cast<size_t*>(context)))++;+            return 0;+            };++         auto custom_destroy_cb = [](void* context) -> void+            {+            (*(static_cast<size_t*>(context)))++;+            };++         if(TEST_FFI_OK(botan_rng_init_custom, (&custom_rng, "custom rng", &cb_counter, custom_get_cb, custom_add_entropy_cb, custom_destroy_cb)))+            {+               Botan::clear_mem(outbuf.data(), outbuf.size());+               TEST_FFI_OK(botan_rng_get, (custom_rng, outbuf.data(), outbuf.size()));+               result.test_eq("custom_get_cb called", cb_counter, 1);+               std::vector<uint8_t> pattern(outbuf.size(), 0x12);+               result.test_eq("custom_get_cb returned bytes", pattern, outbuf);++               TEST_FFI_OK(botan_rng_reseed, (custom_rng, 256));+               result.test_eq("custom_add_entropy_cb called", cb_counter, 2);++               TEST_FFI_OK(botan_rng_reseed_from_rng, (custom_rng, system_rng, 256));+               result.test_eq("custom_add_entropy_cb called", cb_counter, 3);++               uint8_t not_really_entropy[32] = { 0 };+               TEST_FFI_OK(botan_rng_add_entropy, (custom_rng, not_really_entropy, 32));+               result.test_eq("custom_add_entropy_cb called", cb_counter, 4);++               TEST_FFI_OK(botan_rng_destroy, (custom_rng));+               result.test_eq("custom_destroy_cb called", cb_counter, 5);+            }+          TEST_FFI_OK(botan_rng_destroy, (rng));          TEST_FFI_OK(botan_rng_destroy, (null_rng));          TEST_FFI_OK(botan_rng_destroy, (system_rng));@@ -2796,7 +2841,7 @@     }; -BOTAN_REGISTER_TEST("ffi", FFI_Unit_Tests);+BOTAN_REGISTER_TEST("ffi", "ffi", FFI_Unit_Tests);  #endif 
third_party/botan/src/tests/test_filters.cpp view
@@ -785,7 +785,7 @@     }; -BOTAN_REGISTER_TEST("filter", Filter_Tests);+BOTAN_REGISTER_TEST("filters", "filter", Filter_Tests);  #endif 
third_party/botan/src/tests/test_fpe.cpp view
@@ -42,7 +42,7 @@     }; -BOTAN_REGISTER_TEST("fpe_fe1", FPE_FE1_Tests);+BOTAN_REGISTER_TEST("misc", "fpe_fe1", FPE_FE1_Tests);  #endif 
third_party/botan/src/tests/test_gf2m.cpp view
@@ -66,7 +66,7 @@          }    }; -BOTAN_REGISTER_TEST("gf2m", GF2m_Tests);+BOTAN_REGISTER_TEST("pubkey", "gf2m", GF2m_Tests);  #endif 
third_party/botan/src/tests/test_gost_3410.cpp view
@@ -110,9 +110,9 @@          }    }; -BOTAN_REGISTER_TEST("gost_3410_verify", GOST_3410_2001_Verification_Tests);-BOTAN_REGISTER_TEST("gost_3410_sign", GOST_3410_2001_Signature_Tests);-BOTAN_REGISTER_TEST("gost_3410_keygen", GOST_3410_2001_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "gost_3410_verify", GOST_3410_2001_Verification_Tests);+BOTAN_REGISTER_TEST("pubkey", "gost_3410_sign", GOST_3410_2001_Signature_Tests);+BOTAN_REGISTER_TEST("pubkey", "gost_3410_keygen", GOST_3410_2001_Keygen_Tests);  #endif 
third_party/botan/src/tests/test_hash.cpp view
@@ -67,7 +67,7 @@          }    }; -BOTAN_REGISTER_TEST("invalid_name_hash", Invalid_Hash_Name_Tests);+BOTAN_REGISTER_TEST("hash", "invalid_name_hash", Invalid_Hash_Name_Tests);  class Hash_Function_Tests final : public Text_Based_Test    {@@ -178,7 +178,7 @@     }; -BOTAN_REGISTER_TEST("hash", Hash_Function_Tests);+BOTAN_REGISTER_TEST("hash", "hash", Hash_Function_Tests);  class Hash_NIST_MonteCarlo_Tests final : public Text_Based_Test    {@@ -250,7 +250,7 @@          }    }; -BOTAN_REGISTER_TEST("hash_nist_mc", Hash_NIST_MonteCarlo_Tests);+BOTAN_REGISTER_TEST("hash", "hash_nist_mc", Hash_NIST_MonteCarlo_Tests);  class Hash_LongRepeat_Tests final : public Text_Based_Test    {@@ -323,7 +323,7 @@          }    }; -BOTAN_REGISTER_TEST("hash_rep", Hash_LongRepeat_Tests);+BOTAN_REGISTER_TEST("hash", "hash_rep", Hash_LongRepeat_Tests);  } 
third_party/botan/src/tests/test_hash_id.cpp view
@@ -9,7 +9,7 @@ #if defined(BOTAN_HAS_HASH_ID) && defined(BOTAN_HAS_ASN1)   #include <botan/hash_id.h>   #include <botan/der_enc.h>-  #include <botan/alg_id.h>+  #include <botan/asn1_obj.h> #endif  namespace Botan_Tests {@@ -87,7 +87,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs_hash_id", PKCS_HashID_Test);+BOTAN_REGISTER_TEST("pubkey", "pkcs_hash_id", PKCS_HashID_Test); #endif  }
third_party/botan/src/tests/test_kdf.cpp view
@@ -55,7 +55,7 @@     }; -BOTAN_REGISTER_TEST("kdf", KDF_KAT_Tests);+BOTAN_REGISTER_TEST("kdf", "kdf", KDF_KAT_Tests);  #endif @@ -97,7 +97,7 @@     }; -BOTAN_REGISTER_TEST("hkdf_expand_label", HKDF_Expand_Label_Tests);+BOTAN_REGISTER_TEST("kdf", "hkdf_expand_label", HKDF_Expand_Label_Tests);  #endif 
third_party/botan/src/tests/test_keywrap.cpp view
@@ -52,7 +52,7 @@     }; -BOTAN_REGISTER_TEST("rfc3394", RFC3394_Keywrap_Tests);+BOTAN_REGISTER_TEST("keywrap", "rfc3394", RFC3394_Keywrap_Tests); #endif  #if defined(BOTAN_HAS_NIST_KEYWRAP) && defined(BOTAN_HAS_AES)@@ -122,7 +122,7 @@     }; -BOTAN_REGISTER_TEST("nist_key_wrap", NIST_Keywrap_Tests);+BOTAN_REGISTER_TEST("keywrap", "nist_key_wrap", NIST_Keywrap_Tests);  class NIST_Keywrap_Invalid_Tests final : public Text_Based_Test    {@@ -175,7 +175,7 @@     }; -BOTAN_REGISTER_TEST("nist_key_wrap_invalid", NIST_Keywrap_Invalid_Tests);+BOTAN_REGISTER_TEST("keywrap", "nist_key_wrap_invalid", NIST_Keywrap_Invalid_Tests); #endif  }
third_party/botan/src/tests/test_mac.cpp view
@@ -149,7 +149,7 @@          }    }; -BOTAN_REGISTER_TEST("mac", Message_Auth_Tests);+BOTAN_REGISTER_TEST("mac", "mac", Message_Auth_Tests);  #endif 
third_party/botan/src/tests/test_mceliece.cpp view
@@ -112,7 +112,7 @@     }; -BOTAN_REGISTER_TEST("mce_keygen", McEliece_Keygen_Encrypt_Test);+BOTAN_REGISTER_TEST("pubkey", "mce_keygen", McEliece_Keygen_Encrypt_Test); #endif  @@ -279,7 +279,7 @@     }; -BOTAN_REGISTER_TEST("mceliece", McEliece_Tests);+BOTAN_REGISTER_TEST("pubkey", "mceliece", McEliece_Tests);  #endif 
third_party/botan/src/tests/test_modes.cpp view
@@ -252,7 +252,7 @@          }    }; -BOTAN_REGISTER_TEST("modes", Cipher_Mode_Tests);+BOTAN_REGISTER_TEST("modes", "modes", Cipher_Mode_Tests);  class Cipher_Mode_IV_Carry_Tests final : public Test    {@@ -430,7 +430,7 @@    };  -BOTAN_REGISTER_TEST("iv_carryover", Cipher_Mode_IV_Carry_Tests);+BOTAN_REGISTER_TEST("modes", "iv_carryover", Cipher_Mode_IV_Carry_Tests);  #endif 
third_party/botan/src/tests/test_mp.cpp view
@@ -138,7 +138,7 @@          }    }; -BOTAN_REGISTER_TEST("mp_unit", MP_Unit_Tests);+BOTAN_REGISTER_TEST("math", "mp_unit", MP_Unit_Tests);  #endif 
third_party/botan/src/tests/test_name_constraint.cpp view
@@ -88,7 +88,7 @@          }    }; -BOTAN_REGISTER_TEST("x509_path_name_constraint", Name_Constraint_Tests);+BOTAN_REGISTER_TEST("x509", "x509_path_name_constraint", Name_Constraint_Tests);  #endif 
third_party/botan/src/tests/test_newhope.cpp view
@@ -152,7 +152,7 @@          }    }; -BOTAN_REGISTER_TEST("newhope", NEWHOPE_Tests);+BOTAN_REGISTER_TEST("pubkey", "newhope", NEWHOPE_Tests);  #endif 
third_party/botan/src/tests/test_ocb.cpp view
@@ -148,7 +148,7 @@          }    }; -BOTAN_REGISTER_TEST("ocb_wide", OCB_Wide_KAT_Tests);+BOTAN_REGISTER_TEST("modes", "ocb_wide", OCB_Wide_KAT_Tests);  class OCB_Wide_Long_KAT_Tests final : public Text_Based_Test    {@@ -261,7 +261,7 @@          }    }; -BOTAN_REGISTER_TEST("ocb_long_wide", OCB_Wide_Long_KAT_Tests);+BOTAN_REGISTER_TEST("modes", "ocb_long_wide", OCB_Wide_Long_KAT_Tests);  class OCB_Long_KAT_Tests final : public Text_Based_Test    {@@ -358,7 +358,7 @@          }    }; -BOTAN_REGISTER_TEST("ocb_long", OCB_Long_KAT_Tests);+BOTAN_REGISTER_TEST("modes", "ocb_long", OCB_Long_KAT_Tests);  #endif 
third_party/botan/src/tests/test_ocsp.cpp view
@@ -11,7 +11,6 @@    #include <botan/x509path.h>    #include <botan/certstor.h>    #include <botan/calendar.h>-   #include <botan/cert_status.h>    #include <fstream> #endif @@ -370,7 +369,7 @@          }    }; -BOTAN_REGISTER_TEST("ocsp", OCSP_Tests);+BOTAN_REGISTER_TEST("x509", "ocsp", OCSP_Tests);  #endif 
third_party/botan/src/tests/test_octetstring.cpp view
@@ -161,7 +161,7 @@          }    }; -BOTAN_REGISTER_TEST("octetstring", OctetString_Tests);+BOTAN_REGISTER_TEST("utils", "octetstring", OctetString_Tests);  } 
third_party/botan/src/tests/test_oid.cpp view
@@ -106,7 +106,7 @@          }    }; -BOTAN_REGISTER_TEST("oid", OID_Tests);+BOTAN_REGISTER_TEST("asn1", "oid", OID_Tests);  #endif 
third_party/botan/src/tests/test_os_utils.cpp view
@@ -201,7 +201,7 @@          }    }; -BOTAN_REGISTER_TEST("os_utils", OS_Utils_Tests);+BOTAN_REGISTER_TEST("utils", "os_utils", OS_Utils_Tests);  } 
third_party/botan/src/tests/test_otp.cpp view
@@ -7,21 +7,16 @@  #include "tests.h" -#if defined(BOTAN_HAS_HOTP)+#if defined(BOTAN_HAS_HOTP) && defined(BOTAN_HAS_TOTP)    #include <botan/parsing.h>-   #include <botan/hotp.h>+   #include <botan/otp.h>    #include <botan/hash.h>-#endif--#if defined(BOTAN_HAS_TOTP)-   #include <botan/totp.h>    #include <botan/calendar.h>-   #include <botan/hash.h> #endif  namespace Botan_Tests { -#if defined(BOTAN_HAS_HOTP)+#if defined(BOTAN_HAS_HOTP) && defined(BOTAN_HAS_TOTP)  class HOTP_KAT_Tests final : public Text_Based_Test    {@@ -72,11 +67,7 @@          }    }; -BOTAN_REGISTER_TEST("otp_hotp", HOTP_KAT_Tests);--#endif--#if defined(BOTAN_HAS_TOTP)+BOTAN_REGISTER_TEST("otp", "otp_hotp", HOTP_KAT_Tests);  class TOTP_KAT_Tests final : public Text_Based_Test    {@@ -135,7 +126,8 @@          }    }; -BOTAN_REGISTER_TEST("otp_totp", TOTP_KAT_Tests);+BOTAN_REGISTER_TEST("otp", "otp_totp", TOTP_KAT_Tests);+ #endif  }
third_party/botan/src/tests/test_package_transform.cpp view
@@ -65,7 +65,7 @@          }    }; -BOTAN_REGISTER_TEST("package_transform", Package_Transform_Tests);+BOTAN_REGISTER_TEST("misc", "package_transform", Package_Transform_Tests);  #endif 
third_party/botan/src/tests/test_pad.cpp view
@@ -78,7 +78,7 @@          }    }; -BOTAN_REGISTER_TEST("bc_pad", Cipher_Mode_Padding_Tests);+BOTAN_REGISTER_TEST("modes", "bc_pad", Cipher_Mode_Padding_Tests);  #endif 
third_party/botan/src/tests/test_passhash.cpp view
@@ -77,7 +77,7 @@          }    }; -BOTAN_REGISTER_TEST("bcrypt", Bcrypt_Tests);+BOTAN_REGISTER_TEST("pbkdf", "bcrypt", Bcrypt_Tests);  #endif @@ -125,7 +125,7 @@          }    }; -BOTAN_REGISTER_TEST("argon2_pass", Argon2_Tests);+BOTAN_REGISTER_TEST("pbkdf", "argon2_pass", Argon2_Tests);  #endif @@ -201,7 +201,7 @@          }    }; -BOTAN_REGISTER_TEST("passhash9", Passhash9_Tests);+BOTAN_REGISTER_TEST("pbkdf", "passhash9", Passhash9_Tests);  #endif 
third_party/botan/src/tests/test_pbkdf.cpp view
@@ -83,7 +83,7 @@     }; -BOTAN_REGISTER_TEST("pbkdf", PBKDF_KAT_Tests);+BOTAN_REGISTER_TEST("pbkdf", "pbkdf", PBKDF_KAT_Tests);  class Pwdhash_Tests : public Test    {@@ -160,7 +160,7 @@          }    }; -BOTAN_REGISTER_TEST("pwdhash", Pwdhash_Tests);+BOTAN_REGISTER_TEST("pbkdf", "pwdhash", Pwdhash_Tests);  #endif @@ -192,7 +192,7 @@          }    }; -BOTAN_REGISTER_TEST("bcrypt_pbkdf", Bcrypt_PBKDF_KAT_Tests);+BOTAN_REGISTER_TEST("pbkdf", "bcrypt_pbkdf", Bcrypt_PBKDF_KAT_Tests);  #endif @@ -246,7 +246,7 @@     }; -BOTAN_REGISTER_TEST("scrypt", Scrypt_KAT_Tests);+BOTAN_REGISTER_TEST("pbkdf", "scrypt", Scrypt_KAT_Tests);  #endif @@ -317,7 +317,7 @@     }; -BOTAN_REGISTER_TEST("argon2", Argon2_KAT_Tests);+BOTAN_REGISTER_TEST("pbkdf", "argon2", Argon2_KAT_Tests);  #endif @@ -369,7 +369,7 @@          }    }; -BOTAN_REGISTER_TEST("pgp_s2k_iter", PGP_S2K_Iter_Test);+BOTAN_REGISTER_TEST("pbkdf", "pgp_s2k_iter", PGP_S2K_Iter_Test);  #endif 
third_party/botan/src/tests/test_pem.cpp view
@@ -49,7 +49,7 @@          }    }; -BOTAN_REGISTER_TEST("pem", PEM_Tests);+BOTAN_REGISTER_TEST("pubkey", "pem", PEM_Tests);  } 
third_party/botan/src/tests/test_pk_pad.cpp view
@@ -70,7 +70,7 @@          }    }; -BOTAN_REGISTER_TEST("eme_pkcs1v15", EME_PKCS1v15_Decoding_Tests);+BOTAN_REGISTER_TEST("pubkey", "eme_pkcs1v15", EME_PKCS1v15_Decoding_Tests);  class EMSA_unit_tests final : public Test    {@@ -178,7 +178,7 @@          }    }; -BOTAN_REGISTER_TEST("pk_pad_emsa_unit", EMSA_unit_tests);+BOTAN_REGISTER_TEST("pubkey", "pk_pad_emsa_unit", EMSA_unit_tests);  #endif 
third_party/botan/src/tests/test_pkcs11_high_level.cpp view
@@ -17,9 +17,6 @@  #if defined(BOTAN_HAS_PKCS11)    #include <botan/p11.h>-   #include <botan/p11_slot.h>-   #include <botan/p11_session.h>-   #include <botan/p11_module.h>    #include <botan/p11_object.h>    #include <botan/p11_randomgenerator.h> #endif@@ -53,7 +50,7 @@  #if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_HAS_PKCS11)    #include <botan/p11_x509.h>-   #include <botan/x509_dn.h>+   #include <botan/pkix_types.h> #endif  #if defined(BOTAN_HAS_HMAC_DRBG)@@ -203,7 +200,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-module", Module_Tests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-module", Module_Tests);  /***************************** Slot *****************************/ @@ -342,7 +339,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-slot", Slot_Tests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-slot", Slot_Tests);  /***************************** Session *****************************/ @@ -474,7 +471,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-session", Session_Tests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-session", Session_Tests);  /***************************** Object *****************************/ @@ -648,7 +645,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-object", Object_Tests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-object", Object_Tests);  /***************************** PKCS11 RSA *****************************/ @@ -908,7 +905,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-rsa", PKCS11_RSA_Tests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-rsa", PKCS11_RSA_Tests); #endif  /***************************** PKCS11 ECDSA *****************************/@@ -1204,7 +1201,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-ecdsa", PKCS11_ECDSA_Tests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-ecdsa", PKCS11_ECDSA_Tests);  #endif @@ -1430,7 +1427,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-ecdh", PKCS11_ECDH_Tests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-ecdh", PKCS11_ECDH_Tests);  #endif @@ -1516,7 +1513,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-rng", PKCS11_RNG_Tests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-rng", PKCS11_RNG_Tests);  /***************************** PKCS11 token management *****************************/ @@ -1601,7 +1598,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-manage", PKCS11_Token_Management_Tests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-manage", PKCS11_Token_Management_Tests);  /***************************** PKCS11 token management *****************************/ @@ -1645,7 +1642,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-x509", PKCS11_X509_Tests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-x509", PKCS11_X509_Tests);  #endif 
third_party/botan/src/tests/test_pkcs11_low_level.cpp view
@@ -831,7 +831,7 @@          }    }; -BOTAN_REGISTER_TEST("pkcs11-lowlevel", LowLevelTests);+BOTAN_REGISTER_TEST("pkcs11", "pkcs11-lowlevel", LowLevelTests);  #endif #endif
third_party/botan/src/tests/test_psk_db.cpp view
@@ -11,7 +11,6 @@ #include <botan/psk_db.h>  #if defined(BOTAN_HAS_SQLITE3)-  #include <botan/psk_db_sql.h>   #include <botan/sqlite3.h> #endif @@ -252,7 +251,7 @@     }; -BOTAN_REGISTER_TEST("psk_db", PSK_DB_Tests);+BOTAN_REGISTER_TEST("misc", "psk_db", PSK_DB_Tests);  } 
third_party/botan/src/tests/test_rfc6979.cpp view
@@ -51,7 +51,7 @@          }    }; -BOTAN_REGISTER_TEST("rfc6979", RFC6979_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "rfc6979", RFC6979_KAT_Tests);  #endif 
third_party/botan/src/tests/test_rng.cpp view
@@ -573,7 +573,7 @@     }; -BOTAN_REGISTER_TEST("hmac_drbg_unit", HMAC_DRBG_Unit_Tests);+BOTAN_REGISTER_TEST("rng", "hmac_drbg_unit", HMAC_DRBG_Unit_Tests);  #endif @@ -652,7 +652,7 @@     }; -BOTAN_REGISTER_TEST("chacha_rng_unit", ChaCha_RNG_Unit_Tests);+BOTAN_REGISTER_TEST("rng", "chacha_rng_unit", ChaCha_RNG_Unit_Tests);  #endif @@ -739,7 +739,7 @@          }    }; -BOTAN_REGISTER_TEST("auto_rng_unit", AutoSeeded_RNG_Tests);+BOTAN_REGISTER_TEST("rng", "auto_rng_unit", AutoSeeded_RNG_Tests);  #endif @@ -775,7 +775,7 @@          }    }; -BOTAN_REGISTER_TEST("system_rng", System_RNG_Tests);+BOTAN_REGISTER_TEST("rng", "system_rng", System_RNG_Tests);  #endif @@ -828,7 +828,7 @@          }    }; -BOTAN_REGISTER_TEST("processor_rng", Processor_RNG_Tests);+BOTAN_REGISTER_TEST("rng", "processor_rng", Processor_RNG_Tests);  #endif 
third_party/botan/src/tests/test_rng_kat.cpp view
@@ -65,7 +65,7 @@     }; -BOTAN_REGISTER_TEST("hmac_drbg", HMAC_DRBG_Tests);+BOTAN_REGISTER_TEST("rng", "hmac_drbg", HMAC_DRBG_Tests);  #endif @@ -107,7 +107,7 @@     }; -BOTAN_REGISTER_TEST("chacha_rng", ChaCha_RNG_Tests);+BOTAN_REGISTER_TEST("rng", "chacha_rng", ChaCha_RNG_Tests);  #endif 
third_party/botan/src/tests/test_roughtime.cpp view
@@ -47,7 +47,7 @@          }    }; -BOTAN_REGISTER_TEST("roughtime_request", Roughtime_Request_Tests);+BOTAN_REGISTER_TEST("roughtime", "roughtime_request", Roughtime_Request_Tests);   class Roughtime_Response_Tests final : public Text_Based_Test@@ -99,7 +99,7 @@          }    }; -BOTAN_REGISTER_TEST("roughtime_response", Roughtime_Response_Tests);+BOTAN_REGISTER_TEST("roughtime", "roughtime_response", Roughtime_Response_Tests);  class Roughtime_nonce_from_blind_Tests final : public Text_Based_Test    {@@ -123,7 +123,7 @@          }    }; -BOTAN_REGISTER_TEST("roughtime_nonce_from_blind", Roughtime_nonce_from_blind_Tests);+BOTAN_REGISTER_TEST("roughtime", "roughtime_nonce_from_blind", Roughtime_nonce_from_blind_Tests);   @@ -257,7 +257,7 @@          }    }; -BOTAN_REGISTER_TEST("roughtime", Roughtime);+BOTAN_REGISTER_TEST("roughtime", "roughtime", Roughtime);  #endif 
third_party/botan/src/tests/test_rsa.cpp view
@@ -216,6 +216,36 @@          }    }; +class RSA_Keygen_Bad_RNG_Test final : public Test+   {+   public:+      std::vector<Test::Result> run() override+         {+         Test::Result result("RSA keygen with bad RNG");++         /*+         We don't need to count requests here; actually this test+         is relying on the fact that the Request_Counting_RNG outputs+         repeating 808080...+         */+         Request_Counting_RNG rng;++         try+            {+            Botan::RSA_PrivateKey rsa(rng, 1024);+            result.test_failure("Generated a key with a bad RNG");+            }+         catch(Botan::Internal_Error& e)+            {+            result.test_success("Key generation with bad RNG failed");+            result.test_eq("Expected message",+                           e.what(), "Internal error: RNG failure during RSA key generation");+            }++         return {result};+         }+   };+ class RSA_Blinding_Tests final : public Test    {    public:@@ -317,16 +347,17 @@          }    }; -BOTAN_REGISTER_TEST("rsa_encrypt", RSA_ES_KAT_Tests);-BOTAN_REGISTER_TEST("rsa_decrypt", RSA_Decryption_KAT_Tests);-BOTAN_REGISTER_TEST("rsa_sign", RSA_Signature_KAT_Tests);-BOTAN_REGISTER_TEST("rsa_pss", RSA_PSS_KAT_Tests);-BOTAN_REGISTER_TEST("rsa_pss_raw", RSA_PSS_Raw_KAT_Tests);-BOTAN_REGISTER_TEST("rsa_verify", RSA_Signature_Verify_Tests);-BOTAN_REGISTER_TEST("rsa_verify_invalid", RSA_Signature_Verify_Invalid_Tests);-BOTAN_REGISTER_TEST("rsa_kem", RSA_KEM_Tests);-BOTAN_REGISTER_TEST("rsa_keygen", RSA_Keygen_Tests);-BOTAN_REGISTER_TEST("rsa_blinding", RSA_Blinding_Tests);+BOTAN_REGISTER_TEST("pubkey", "rsa_encrypt", RSA_ES_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "rsa_decrypt", RSA_Decryption_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "rsa_sign", RSA_Signature_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "rsa_pss", RSA_PSS_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "rsa_pss_raw", RSA_PSS_Raw_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "rsa_verify", RSA_Signature_Verify_Tests);+BOTAN_REGISTER_TEST("pubkey", "rsa_verify_invalid", RSA_Signature_Verify_Invalid_Tests);+BOTAN_REGISTER_TEST("pubkey", "rsa_kem", RSA_KEM_Tests);+BOTAN_REGISTER_TEST("pubkey", "rsa_keygen", RSA_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "rsa_keygen_badrng", RSA_Keygen_Bad_RNG_Test);+BOTAN_REGISTER_TEST("pubkey", "rsa_blinding", RSA_Blinding_Tests);  #endif 
third_party/botan/src/tests/test_runner.cpp view
@@ -8,7 +8,6 @@ #include "tests.h"  #include <botan/version.h>-#include <botan/rotate.h> #include <botan/loadstor.h> #include <botan/cpuid.h> @@ -76,15 +75,16 @@           for(size_t i = 0; i != ROUNDS; ++i)             {-            m_a += static_cast<uint32_t>(i);+            m_a += static_cast<uint32_t>(i ^ 0x5555); -            m_a = Botan::rotl<9>(m_a);+            m_a *= 0x9e3779b9;             m_b ^= m_a;             m_d ^= m_c;              m_a += m_d;             m_c += m_b;-            m_c = Botan::rotl<23>(m_c);++            m_c += (m_c >> 17);             }          } 
third_party/botan/src/tests/test_simd.cpp view
@@ -196,7 +196,7 @@     }; -BOTAN_REGISTER_TEST("simd_32", SIMD_32_Tests);+BOTAN_REGISTER_TEST("utils", "simd_32", SIMD_32_Tests); #endif  }
third_party/botan/src/tests/test_siv.cpp view
@@ -7,8 +7,7 @@ #include "tests.h"  #if defined(BOTAN_HAS_AEAD_SIV)-   #include <botan/siv.h>-   #include <botan/block_cipher.h>+   #include <botan/aead.h>    #include <botan/parsing.h> #endif @@ -32,18 +31,18 @@          const std::vector<std::string> ad_list =             Botan::split_on(vars.get_req_str("ADs"), ','); -         Test::Result result(algo + "/SIV");+         const std::string siv_name = algo + "/SIV"; -         auto cipher = Botan::BlockCipher::create(algo);+         Test::Result result(siv_name); -         if(!cipher)+         auto siv = Botan::AEAD_Mode::create(siv_name, Botan::ENCRYPTION);++         if(!siv)             {             result.test_note("Skipping test due to missing cipher");             return result;             } -         std::unique_ptr<Botan::SIV_Mode> siv(new Botan::SIV_Encryption(cipher.release()));-          siv->set_key(key);           for(size_t i = 0; i != ad_list.size(); ++i)@@ -63,7 +62,7 @@     }; -BOTAN_REGISTER_TEST("siv_ad", SIV_Tests);+BOTAN_REGISTER_TEST("modes", "siv_ad", SIV_Tests);  #endif 
third_party/botan/src/tests/test_sm2.cpp view
@@ -64,7 +64,7 @@          }    }; -BOTAN_REGISTER_TEST("sm2_sig", SM2_Signature_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "sm2_sig", SM2_Signature_KAT_Tests);  class SM2_Encryption_KAT_Tests final : public PK_Encryption_Decryption_Test    {@@ -96,7 +96,7 @@  } -BOTAN_REGISTER_TEST("sm2_enc", SM2_Encryption_KAT_Tests);+BOTAN_REGISTER_TEST("pubkey", "sm2_enc", SM2_Encryption_KAT_Tests);  class SM2_Keygen_Tests final : public PK_Key_Generation_Test    {@@ -112,7 +112,7 @@          }    }; -BOTAN_REGISTER_TEST("sm2_keygen", SM2_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "sm2_keygen", SM2_Keygen_Tests);   #endif
third_party/botan/src/tests/test_sodium.cpp view
@@ -665,7 +665,7 @@     }; -BOTAN_REGISTER_TEST("sodium", Sodium_API_Tests);+BOTAN_REGISTER_TEST("compat", "sodium", Sodium_API_Tests);  #endif 
third_party/botan/src/tests/test_srp6.cpp view
@@ -86,7 +86,7 @@          }    }; -BOTAN_REGISTER_TEST("srp6_kat", SRP6_KAT_Tests);+BOTAN_REGISTER_TEST("pake", "srp6_kat", SRP6_KAT_Tests);  #if defined(BOTAN_HAS_SHA2_32) @@ -123,7 +123,7 @@          }    }; -BOTAN_REGISTER_TEST("srp6", SRP6_RT_Tests);+BOTAN_REGISTER_TEST("pake", "srp6", SRP6_RT_Tests);  #endif 
third_party/botan/src/tests/test_stream.cpp view
@@ -186,7 +186,7 @@          }    }; -BOTAN_REGISTER_TEST("stream", Stream_Cipher_Tests);+BOTAN_REGISTER_TEST("stream", "stream", Stream_Cipher_Tests);  #endif 
third_party/botan/src/tests/test_tests.cpp view
@@ -177,10 +177,34 @@             } #endif -         return {result};+         return {result, test_testsuite_rng()};          }     private:+      Test::Result test_testsuite_rng()+         {+         Test::Result result("Testsuite_RNG");++         size_t histogram[256] = { 0 };++         const size_t RUNS = 1000;++         for(size_t i = 0; i != 256 * RUNS; ++i)+            {+            histogram[rng().next_byte()] += 1;+            }++         for(size_t i = 0; i != 256; ++i)+            {+            if(histogram[i] < RUNS / 2 || histogram[i] > RUNS * 2)+               result.test_failure("Testsuite_RNG produced non-uniform output");+            else+               result.test_success("Testsuite_RNG seemed roughly uniform");+            }++         return result;+         }+       void verify_failure(const std::string& what,                           Test::Result& result,                           const Test::Result& test_result)@@ -198,6 +222,6 @@          }    }; -BOTAN_REGISTER_TEST("testcode", Test_Tests);+BOTAN_REGISTER_TEST("utils", "testcode", Test_Tests);  }
third_party/botan/src/tests/test_thread_utils.cpp view
@@ -65,7 +65,7 @@    return result;    } -BOTAN_REGISTER_TEST_FN("thread_pool", thread_pool);+BOTAN_REGISTER_TEST_FN("utils", "thread_pool", thread_pool);  } 
third_party/botan/src/tests/test_tls.cpp view
@@ -86,7 +86,7 @@          }    }; -BOTAN_REGISTER_TEST("tls_session", TLS_Session_Tests);+BOTAN_REGISTER_TEST("tls", "tls_session", TLS_Session_Tests);  #if defined(BOTAN_HAS_TLS_CBC) @@ -108,7 +108,7 @@          }    }; -BOTAN_REGISTER_TEST("tls_cbc_padding", TLS_CBC_Padding_Tests);+BOTAN_REGISTER_TEST("tls", "tls_cbc_padding", TLS_CBC_Padding_Tests);  class TLS_CBC_Tests final : public Text_Based_Test    {@@ -221,7 +221,7 @@          }    }; -BOTAN_REGISTER_TEST("tls_cbc", TLS_CBC_Tests);+BOTAN_REGISTER_TEST("tls", "tls_cbc", TLS_CBC_Tests);  #endif @@ -285,7 +285,7 @@          }    }; -BOTAN_REGISTER_TEST("tls_alert_strings", Test_TLS_Alert_Strings);+BOTAN_REGISTER_TEST("tls", "tls_alert_strings", Test_TLS_Alert_Strings);  class Test_TLS_Policy_Text : public Test    {@@ -364,7 +364,7 @@          }    }; -BOTAN_REGISTER_TEST("tls_policy_text", Test_TLS_Policy_Text);+BOTAN_REGISTER_TEST("tls", "tls_policy_text", Test_TLS_Policy_Text);  class Test_TLS_Ciphersuites : public Test    {@@ -399,7 +399,7 @@          }    }; -BOTAN_REGISTER_TEST("tls_ciphersuites", Test_TLS_Ciphersuites);+BOTAN_REGISTER_TEST("tls", "tls_ciphersuites", Test_TLS_Ciphersuites);  class Test_TLS_Algo_Strings : public Test    {@@ -487,7 +487,7 @@     }; -BOTAN_REGISTER_TEST("tls_algo_strings", Test_TLS_Algo_Strings);+BOTAN_REGISTER_TEST("tls", "tls_algo_strings", Test_TLS_Algo_Strings);  #endif 
third_party/botan/src/tests/test_tls_messages.cpp view
@@ -225,7 +225,7 @@          }    }; -BOTAN_REGISTER_TEST("tls_messages", TLS_Message_Parsing_Test);+BOTAN_REGISTER_TEST("tls", "tls_messages", TLS_Message_Parsing_Test);  #endif 
third_party/botan/src/tests/test_tls_stream_integration.cpp view
@@ -718,7 +718,7 @@          }    }; -BOTAN_REGISTER_TEST("tls_stream_integration", Tls_Stream_Integration_Tests);+BOTAN_REGISTER_TEST("tls", "tls_stream_integration", Tls_Stream_Integration_Tests);  }  // namespace Botan_Tests 
third_party/botan/src/tests/test_tpm.cpp view
@@ -79,7 +79,7 @@     }; -BOTAN_REGISTER_TEST("tpm", TPM_Tests);+BOTAN_REGISTER_TEST("tpm", "tpm", TPM_Tests);  class UUID_Tests final : public Test    {@@ -108,7 +108,7 @@          }    }; -BOTAN_REGISTER_TEST("tpm_uuid", UUID_Tests);+BOTAN_REGISTER_TEST("tpm", "tpm_uuid", UUID_Tests);  #endif 
third_party/botan/src/tests/test_tss.cpp view
@@ -78,7 +78,7 @@          }    }; -BOTAN_REGISTER_TEST("tss_recovery", TSS_Recovery_Tests);+BOTAN_REGISTER_TEST("utils", "tss_recovery", TSS_Recovery_Tests);  class TSS_Generation_Tests final : public Text_Based_Test    {@@ -154,7 +154,7 @@          }    }; -BOTAN_REGISTER_TEST("tss_generation", TSS_Generation_Tests);+BOTAN_REGISTER_TEST("utils", "tss_generation", TSS_Generation_Tests);  #endif // BOTAN_HAS_THRESHOLD_SECRET_SHARING 
third_party/botan/src/tests/test_uri.cpp view
@@ -113,7 +113,7 @@          }    }; -BOTAN_REGISTER_TEST("uri", URI_Tests);+BOTAN_REGISTER_TEST("utils", "uri", URI_Tests);  }  // namespace Botan_Tests 
third_party/botan/src/tests/test_utils.cpp view
@@ -197,7 +197,7 @@          }    }; -BOTAN_REGISTER_TEST("util", Utility_Function_Tests);+BOTAN_REGISTER_TEST("utils", "util", Utility_Function_Tests);  class CT_Mask_Tests final : public Test    {@@ -236,7 +236,7 @@          }    }; -BOTAN_REGISTER_TEST("ct_utils", CT_Mask_Tests);+BOTAN_REGISTER_TEST("utils", "ct_utils", CT_Mask_Tests);  class BitOps_Tests final : public Test    {@@ -331,7 +331,7 @@          }    }; -BOTAN_REGISTER_TEST("bit_ops", BitOps_Tests);+BOTAN_REGISTER_TEST("utils", "bit_ops", BitOps_Tests);  #if defined(BOTAN_HAS_POLY_DBL) @@ -354,7 +354,7 @@          }    }; -BOTAN_REGISTER_TEST("poly_dbl", Poly_Double_Tests);+BOTAN_REGISTER_TEST("utils", "poly_dbl", Poly_Double_Tests);  #endif @@ -405,7 +405,7 @@          }    }; -BOTAN_REGISTER_TEST("versioning", Version_Tests);+BOTAN_REGISTER_TEST("utils", "versioning", Version_Tests);  class Date_Format_Tests final : public Text_Based_Test    {@@ -482,7 +482,7 @@          }    }; -BOTAN_REGISTER_TEST("util_dates", Date_Format_Tests);+BOTAN_REGISTER_TEST("utils", "util_dates", Date_Format_Tests);  #if defined(BOTAN_HAS_BASE32_CODEC) @@ -560,7 +560,7 @@          }    }; -BOTAN_REGISTER_TEST("base32", Base32_Tests);+BOTAN_REGISTER_TEST("utils", "base32", Base32_Tests);  #endif @@ -608,7 +608,7 @@          }    }; -BOTAN_REGISTER_TEST("base58", Base58_Tests);+BOTAN_REGISTER_TEST("utils", "base58", Base58_Tests);  class Base58_Check_Tests final : public Text_Based_Test    {@@ -652,7 +652,7 @@          }    }; -BOTAN_REGISTER_TEST("base58c", Base58_Check_Tests);+BOTAN_REGISTER_TEST("utils", "base58c", Base58_Check_Tests);  #endif @@ -732,7 +732,7 @@          }    }; -BOTAN_REGISTER_TEST("base64", Base64_Tests);+BOTAN_REGISTER_TEST("utils", "base64", Base64_Tests);  #endif @@ -858,7 +858,7 @@     }; -BOTAN_REGISTER_TEST("charset", Charset_Tests);+BOTAN_REGISTER_TEST("utils", "charset", Charset_Tests);  class Hostname_Tests final : public Text_Based_Test    {@@ -882,7 +882,7 @@          }    }; -BOTAN_REGISTER_TEST("hostname", Hostname_Tests);+BOTAN_REGISTER_TEST("utils", "hostname", Hostname_Tests);  class ReadKV_Tests final : public Text_Based_Test    {@@ -959,7 +959,7 @@          }    }; -BOTAN_REGISTER_TEST("util_read_kv", ReadKV_Tests);+BOTAN_REGISTER_TEST("utils", "util_read_kv", ReadKV_Tests);  class CPUID_Tests final : public Test    {@@ -1009,7 +1009,7 @@          }    }; -BOTAN_REGISTER_TEST("cpuid", CPUID_Tests);+BOTAN_REGISTER_TEST("utils", "cpuid", CPUID_Tests);  #if defined(BOTAN_HAS_UUID) @@ -1077,7 +1077,7 @@     }; -BOTAN_REGISTER_TEST("uuid", UUID_Tests);+BOTAN_REGISTER_TEST("utils", "uuid", UUID_Tests);  #endif 
third_party/botan/src/tests/test_workfactor.cpp view
@@ -44,7 +44,7 @@          }    }; -BOTAN_REGISTER_TEST("pk_workfactor", PK_Workfactor_Tests);+BOTAN_REGISTER_TEST("pubkey", "pk_workfactor", PK_Workfactor_Tests); #endif  }
third_party/botan/src/tests/test_x509_dn.cpp view
@@ -7,7 +7,7 @@ #include "tests.h"  #if defined(BOTAN_HAS_X509_CERTIFICATES)-   #include <botan/x509_dn.h>+   #include <botan/pkix_types.h>    #include <botan/ber_dec.h> #endif @@ -63,7 +63,7 @@          }    }; -BOTAN_REGISTER_TEST("x509_dn_cmp", X509_DN_Comparisons_Tests);+BOTAN_REGISTER_TEST("x509", "x509_dn_cmp", X509_DN_Comparisons_Tests); #endif  }
third_party/botan/src/tests/test_x509_path.cpp view
@@ -7,6 +7,7 @@ #include "tests.h"  #if defined(BOTAN_HAS_X509_CERTIFICATES)+   #include <botan/x509_key.h>    #include <botan/x509path.h>    #include <botan/calendar.h>    #include <botan/internal/filesystem.h>@@ -181,7 +182,7 @@     }; -BOTAN_REGISTER_TEST("x509_path_x509test", X509test_Path_Validation_Tests);+BOTAN_REGISTER_TEST("x509", "x509_path_x509test", X509test_Path_Validation_Tests);  class NIST_Path_Validation_Tests final : public Test    {@@ -289,7 +290,7 @@    return results;    } -BOTAN_REGISTER_TEST("x509_path_nist", NIST_Path_Validation_Tests);+BOTAN_REGISTER_TEST("x509", "x509_path_nist", NIST_Path_Validation_Tests);  class Extended_Path_Validation_Tests final : public Test    {@@ -365,7 +366,7 @@    return results;    } -BOTAN_REGISTER_TEST("x509_path_extended", Extended_Path_Validation_Tests);+BOTAN_REGISTER_TEST("x509", "x509_path_extended", Extended_Path_Validation_Tests);  class PSS_Path_Validation_Tests : public Test    {@@ -482,7 +483,7 @@    return results;    } -BOTAN_REGISTER_TEST("x509_path_rsa_pss", PSS_Path_Validation_Tests);+BOTAN_REGISTER_TEST("x509", "x509_path_rsa_pss", PSS_Path_Validation_Tests);  class Validate_V1Cert_Test final : public Test    {@@ -539,7 +540,7 @@    return {result};    } -BOTAN_REGISTER_TEST("x509_v1_ca", Validate_V1Cert_Test);+BOTAN_REGISTER_TEST("x509", "x509_v1_ca", Validate_V1Cert_Test);  class Validate_V2Uid_in_V1_Test final : public Test    {@@ -588,7 +589,7 @@    return {result};    } -BOTAN_REGISTER_TEST("x509_v2uid_in_v1", Validate_V2Uid_in_V1_Test);+BOTAN_REGISTER_TEST("x509", "x509_v2uid_in_v1", Validate_V2Uid_in_V1_Test);  class Validate_Name_Constraint_SAN_Test final : public Test    {@@ -637,8 +638,100 @@    return {result};    } -BOTAN_REGISTER_TEST("x509_name_constraint_san", Validate_Name_Constraint_SAN_Test);+BOTAN_REGISTER_TEST("x509", "x509_name_constraint_san", Validate_Name_Constraint_SAN_Test); +class Validate_Name_Constraint_CaseInsensitive final : public Test+   {+   public:+      std::vector<Test::Result> run() override;+   };++std::vector<Test::Result> Validate_Name_Constraint_CaseInsensitive::run()+   {+   if(Botan::has_filesystem_impl() == false)+      {+      return {Test::Result::Note("Path validation",+                                 "Skipping due to missing filesystem access")};+      }++   std::vector<Test::Result> results;++   const std::string root_crt = Test::data_file("/x509/misc/name_constraint_ci/root.pem");+   const std::string int_crt  = Test::data_file("/x509/misc/name_constraint_ci/int.pem");+   const std::string ee_crt   = Test::data_file("/x509/misc/name_constraint_ci/leaf.pem");++   auto validation_time =+      Botan::calendar_point(2021, 5, 8, 1, 0, 0).to_std_timepoint();++   Botan::X509_Certificate root(root_crt);+   Botan::X509_Certificate intermediate(int_crt);+   Botan::X509_Certificate ee_cert(ee_crt);++   Botan::Certificate_Store_In_Memory trusted;+   trusted.add_certificate(root);++   std::vector<Botan::X509_Certificate> chain = { ee_cert, intermediate };++   Botan::Path_Validation_Restrictions restrictions;+   Botan::Path_Validation_Result validation_result =+      Botan::x509_path_validate(chain, restrictions, trusted, "",+                                Botan::Usage_Type::UNSPECIFIED, validation_time);++   Test::Result result("DNS name constraints are case insensitive");+   result.test_eq("Path validation succeeded",+                  validation_result.successful_validation(), true);++   return {result};+   }++BOTAN_REGISTER_TEST("x509", "x509_name_constraint_ci", Validate_Name_Constraint_CaseInsensitive);++class Validate_Name_Constraint_NoCheckSelf final : public Test+   {+   public:+      std::vector<Test::Result> run() override;+   };++std::vector<Test::Result> Validate_Name_Constraint_NoCheckSelf::run()+   {+   if(Botan::has_filesystem_impl() == false)+      {+      return {Test::Result::Note("Path validation",+                                 "Skipping due to missing filesystem access")};+      }++   std::vector<Test::Result> results;++   const std::string root_crt = Test::data_file("/x509/misc/nc_skip_self/root.pem");+   const std::string int_crt  = Test::data_file("/x509/misc/nc_skip_self/int.pem");+   const std::string ee_crt   = Test::data_file("/x509/misc/nc_skip_self/leaf.pem");++   auto validation_time =+      Botan::calendar_point(2021, 5, 8, 1, 0, 0).to_std_timepoint();++   Botan::X509_Certificate root(root_crt);+   Botan::X509_Certificate intermediate(int_crt);+   Botan::X509_Certificate ee_cert(ee_crt);++   Botan::Certificate_Store_In_Memory trusted;+   trusted.add_certificate(root);++   std::vector<Botan::X509_Certificate> chain = { ee_cert, intermediate };++   Botan::Path_Validation_Restrictions restrictions;+   Botan::Path_Validation_Result validation_result =+      Botan::x509_path_validate(chain, restrictions, trusted, "",+                                Botan::Usage_Type::UNSPECIFIED, validation_time);++   Test::Result result("Name constraints do not apply to the certificate which includes them");+   result.test_eq("Path validation succeeded",+                  validation_result.successful_validation(), true);++   return {result};+   }++BOTAN_REGISTER_TEST("x509", "x509_name_constraint_no_check_self", Validate_Name_Constraint_NoCheckSelf);+ class BSI_Path_Validation_Tests final : public Test     {@@ -812,7 +905,7 @@    return results;    } -BOTAN_REGISTER_TEST("x509_path_bsi", BSI_Path_Validation_Tests);+BOTAN_REGISTER_TEST("x509", "x509_path_bsi", BSI_Path_Validation_Tests);  class Path_Validation_With_OCSP_Tests final : public Test    {@@ -993,7 +1086,7 @@     }; -BOTAN_REGISTER_TEST("x509_path_with_ocsp", Path_Validation_With_OCSP_Tests);+BOTAN_REGISTER_TEST("x509", "x509_path_with_ocsp", Path_Validation_With_OCSP_Tests);  #endif @@ -1051,7 +1144,7 @@          }    }; -BOTAN_REGISTER_TEST("x509_cve_2020_0601", CVE_2020_0601_Tests);+BOTAN_REGISTER_TEST("x509", "x509_cve_2020_0601", CVE_2020_0601_Tests);  #endif @@ -1091,7 +1184,7 @@       }    }; -BOTAN_REGISTER_TEST("x509_path_xmss", XMSS_Path_Validation_Tests);+BOTAN_REGISTER_TEST("x509", "x509_path_xmss", XMSS_Path_Validation_Tests);  #endif 
third_party/botan/src/tests/test_xmss.cpp view
@@ -117,10 +117,10 @@          }    }; -BOTAN_REGISTER_TEST("xmss_sign", XMSS_Signature_Tests);-BOTAN_REGISTER_TEST("xmss_verify", XMSS_Signature_Verify_Tests);-BOTAN_REGISTER_TEST("xmss_verify_invalid", XMSS_Signature_Verify_Invalid_Tests);-BOTAN_REGISTER_TEST("xmss_keygen", XMSS_Keygen_Tests);+BOTAN_REGISTER_TEST("pubkey", "xmss_sign", XMSS_Signature_Tests);+BOTAN_REGISTER_TEST("pubkey", "xmss_verify", XMSS_Signature_Verify_Tests);+BOTAN_REGISTER_TEST("pubkey", "xmss_verify_invalid", XMSS_Signature_Verify_Invalid_Tests);+BOTAN_REGISTER_TEST("pubkey", "xmss_keygen", XMSS_Keygen_Tests);  #endif 
third_party/botan/src/tests/tests.cpp view
@@ -480,9 +480,11 @@    }  //static-void Test::register_test(const std::string& name,+void Test::register_test(const std::string& category,+                         const std::string& name,                          std::function<Test* ()> maker_fn)    {+   BOTAN_UNUSED(category);    if(Test::global_registry().count(name) != 0)       throw Test_Error("Duplicate registration of test '" + name + "'"); 
third_party/botan/src/tests/tests.h view
@@ -233,9 +233,9 @@                test_failure(what, buf.data(), buf.size());                } -            bool confirm(const std::string& what, bool expr)+            bool confirm(const std::string& what, bool expr, bool expected = true)                {-               return test_eq(what, expr, true);+               return test_eq(what, expr, expected);                }              template<typename T>@@ -432,7 +432,8 @@        virtual std::vector<std::string> possible_providers(const std::string&); -      static void register_test(const std::string& name,+      static void register_test(const std::string& category,+                                const std::string& name,                                 std::function<Test* ()> maker_fn);        static std::map<std::string, std::function<Test* ()>>& global_registry();@@ -506,15 +507,15 @@ class TestClassRegistration    {    public:-      TestClassRegistration(const std::string& name)+      TestClassRegistration(const std::string& category, const std::string& name)          {          auto test_maker = []() -> Test* { return new Test_Class; };-         Test::register_test(name, test_maker);+         Test::register_test(category, name, test_maker);          }    }; -#define BOTAN_REGISTER_TEST(name, Test_Class)                 \-   TestClassRegistration<Test_Class> reg_ ## Test_Class ## _tests(name)+#define BOTAN_REGISTER_TEST(category, name, Test_Class)                 \+   TestClassRegistration<Test_Class> reg_ ## Test_Class ## _tests(category, name)  typedef Test::Result (*test_fn)(); @@ -535,15 +536,15 @@ class TestFnRegistration    {    public:-      TestFnRegistration(const std::string& name, test_fn fn)+      TestFnRegistration(const std::string& category, const std::string& name, test_fn fn)          {          auto test_maker = [=]() -> Test* { return new FnTest(fn); };-         Test::register_test(name, test_maker);+         Test::register_test(category, name, test_maker);          }    }; -#define BOTAN_REGISTER_TEST_FN(name, fn_name)         \-   TestFnRegistration reg_ ## fn_name(name, fn_name)+#define BOTAN_REGISTER_TEST_FN(category, name, fn_name) \+   TestFnRegistration reg_ ## fn_name(category, name, fn_name)  class VarMap    {
third_party/botan/src/tests/unit_asio_stream.cpp view
@@ -809,7 +809,7 @@          }    }; -BOTAN_REGISTER_TEST("tls_asio_stream", Asio_Stream_Tests);+BOTAN_REGISTER_TEST("tls", "tls_asio_stream", Asio_Stream_Tests);  }  // namespace Botan_Tests 
third_party/botan/src/tests/unit_ecc.cpp view
@@ -179,7 +179,7 @@    return results;    } -BOTAN_REGISTER_TEST("ecc_randomized", ECC_Randomized_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecc_randomized", ECC_Randomized_Tests);  class NIST_Curve_Reduction_Tests final : public Test    {@@ -260,7 +260,7 @@          }    }; -BOTAN_REGISTER_TEST("nist_redc", NIST_Curve_Reduction_Tests);+BOTAN_REGISTER_TEST("pubkey", "nist_redc", NIST_Curve_Reduction_Tests);  class EC_Group_Tests : public Test    {@@ -427,7 +427,7 @@     }; -BOTAN_REGISTER_TEST("ec_group", EC_Group_Tests);+BOTAN_REGISTER_TEST("pubkey", "ec_group", EC_Group_Tests);  Test::Result test_decoding_with_seed()    {@@ -710,7 +710,7 @@          }    }; -BOTAN_REGISTER_TEST("ecc_unit", ECC_Unit_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecc_unit", ECC_Unit_Tests);  #if defined(BOTAN_HAS_ECDSA) @@ -746,7 +746,7 @@          }    }; -BOTAN_REGISTER_TEST("ecc_invalid", ECC_Invalid_Key_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecc_invalid", ECC_Invalid_Key_Tests);  #endif 
third_party/botan/src/tests/unit_ecdh.cpp view
@@ -68,7 +68,7 @@     }; -BOTAN_REGISTER_TEST("ecdh_unit", ECDH_Unit_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecdh_unit", ECDH_Unit_Tests);  #endif 
third_party/botan/src/tests/unit_ecdsa.cpp view
@@ -460,7 +460,7 @@          }    }; -BOTAN_REGISTER_TEST("ecdsa_unit", ECDSA_Unit_Tests);+BOTAN_REGISTER_TEST("pubkey", "ecdsa_unit", ECDSA_Unit_Tests); #endif  }
third_party/botan/src/tests/unit_tls.cpp view
@@ -271,7 +271,7 @@    std::unique_ptr<Botan::X509_Certificate> dsa_ca_cert;  #if defined(BOTAN_HAS_DSA)-   const Botan::DL_Group dsa_params("modp/ietf/2048");+   const Botan::DL_Group dsa_params("dsa/jce/1024");     dsa_ca_key.reset(new Botan::DSA_PrivateKey(rng, dsa_params));    dsa_srv_key.reset(new Botan::DSA_PrivateKey(rng, dsa_params));@@ -781,6 +781,11 @@          return 1024;          } +      size_t minimum_dsa_group_size() const override+         {+         return 1024;+         }+       size_t minimum_signature_strength() const override          {          return 80;@@ -973,11 +978,14 @@          test_modern_versions("AES-128 DH", results, *client_ses, *server_ses, *creds, "DH", "AES-128", "SHA-256");  #if defined(BOTAN_HAS_DSA)-         test_modern_versions("AES-128 DSA", results, *client_ses, *server_ses, *creds, "DH", "AES-128", "SHA-256",-                              { { "signature_methods", "DSA" } });+         if(Test::run_long_tests())+            {+            test_modern_versions("AES-128 DSA", results, *client_ses, *server_ses, *creds, "DH", "AES-128", "SHA-256",+                                 { { "signature_methods", "DSA" } }); -         test_modern_versions("AES-128/GCM DSA", results, *client_ses, *server_ses, *creds, "DH", "AES-128/GCM", "AEAD",-                              { { "signature_methods", "DSA" } });+            test_modern_versions("AES-128/GCM DSA", results, *client_ses, *server_ses, *creds, "DH", "AES-128/GCM", "AEAD",+                                 { { "signature_methods", "DSA" } });+            } #endif  #if defined(BOTAN_HAS_SRP6)@@ -1122,7 +1130,7 @@     }; -BOTAN_REGISTER_TEST("tls", TLS_Unit_Tests);+BOTAN_REGISTER_TEST("tls", "tls", TLS_Unit_Tests);  class DTLS_Reconnection_Test : public Test    {@@ -1357,7 +1365,7 @@          }    }; -BOTAN_REGISTER_TEST("tls_dtls_reconnect", DTLS_Reconnection_Test);+BOTAN_REGISTER_TEST("tls", "tls_dtls_reconnect", DTLS_Reconnection_Test);  #endif 
third_party/botan/src/tests/unit_tls_policy.cpp view
@@ -183,7 +183,7 @@     }; -BOTAN_REGISTER_TEST("tls_policy", TLS_Policy_Unit_Tests);+BOTAN_REGISTER_TEST("tls", "tls_policy", TLS_Policy_Unit_Tests);  #endif 
third_party/botan/src/tests/unit_x509.cpp view
@@ -14,6 +14,7 @@    #include <botan/x509self.h>    #include <botan/x509path.h>    #include <botan/x509_ca.h>+   #include <botan/x509_ext.h>    #include <botan/pk_algs.h>    #include <botan/ber_dec.h>    #include <botan/der_enc.h>@@ -459,6 +460,20 @@    return result;    } +Test::Result test_rdn_multielement_set_name()+   {+   Test::Result result("DN with multiple elements in RDN");++   // GH #2611++   Botan::X509_Certificate cert(Test::data_file("x509/misc/rdn_set.crt"));++   result.confirm("contains expected name components",+                  cert.issuer_dn().get_attributes().size() == 4);++   return result;+   }+ Test::Result test_rsa_oaep()    {    Test::Result result("RSA OAEP decoding");@@ -1717,6 +1732,7 @@          results.push_back(test_x509_utf8());          results.push_back(test_x509_bmpstring());          results.push_back(test_crl_dn_name());+         results.push_back(test_rdn_multielement_set_name());          results.push_back(test_x509_decode_list());          results.push_back(test_rsa_oaep());          results.push_back(test_x509_authority_info_access_extension());@@ -1732,7 +1748,7 @@          }    }; -BOTAN_REGISTER_TEST("x509_unit", X509_Cert_Unit_Tests);+BOTAN_REGISTER_TEST("x509", "x509_unit", X509_Cert_Unit_Tests);  #endif