diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/compat/sodium/info.txt | 17 | ||||
-rw-r--r-- | src/lib/compat/sodium/sodium.h | 1453 | ||||
-rw-r--r-- | src/lib/compat/sodium/sodium_25519.cpp | 60 | ||||
-rw-r--r-- | src/lib/compat/sodium/sodium_aead.cpp | 359 | ||||
-rw-r--r-- | src/lib/compat/sodium/sodium_auth.cpp | 131 | ||||
-rw-r--r-- | src/lib/compat/sodium/sodium_box.cpp | 100 | ||||
-rw-r--r-- | src/lib/compat/sodium/sodium_chacha.cpp | 109 | ||||
-rw-r--r-- | src/lib/compat/sodium/sodium_salsa.cpp | 124 | ||||
-rw-r--r-- | src/lib/compat/sodium/sodium_secretbox.cpp | 123 | ||||
-rw-r--r-- | src/lib/compat/sodium/sodium_utils.cpp | 156 | ||||
-rw-r--r-- | src/lib/stream/salsa20/salsa20.cpp | 7 | ||||
-rw-r--r-- | src/lib/stream/salsa20/salsa20.h | 1 |
12 files changed, 2635 insertions, 5 deletions
diff --git a/src/lib/compat/sodium/info.txt b/src/lib/compat/sodium/info.txt new file mode 100644 index 000000000..4adc853d9 --- /dev/null +++ b/src/lib/compat/sodium/info.txt @@ -0,0 +1,17 @@ +<defines> +SODIUM_API -> 20190615 +</defines> + +<requires> +chacha +salsa20 +poly1305 +chacha20poly1305 +curve25519 +ed25519 +sha2_32 +sha2_64 +hmac +siphash +system_rng +</requires> diff --git a/src/lib/compat/sodium/sodium.h b/src/lib/compat/sodium/sodium.h new file mode 100644 index 000000000..4bb37e974 --- /dev/null +++ b/src/lib/compat/sodium/sodium.h @@ -0,0 +1,1453 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SODIUM_COMPAT_H_ +#define BOTAN_SODIUM_COMPAT_H_ + +#include <botan/types.h> + +namespace Botan { + +/** +* The Sodium namespace contains a partial implementation of the +* libsodium API. +*/ +namespace Sodium { + +// sodium/randombytes.h +enum Sodium_Constants { + SODIUM_SIZE_MAX = 0xFFFFFFFF, + + crypto_aead_chacha20poly1305_ABYTES = 16, + crypto_aead_chacha20poly1305_KEYBYTES = 32, + crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX = SODIUM_SIZE_MAX, + crypto_aead_chacha20poly1305_NPUBBYTES = 8, + crypto_aead_chacha20poly1305_NSECBYTES = 0, + + crypto_aead_chacha20poly1305_ietf_ABYTES = 16, + crypto_aead_chacha20poly1305_ietf_KEYBYTES = 32, + crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX = SODIUM_SIZE_MAX, + crypto_aead_chacha20poly1305_ietf_NPUBBYTES = 12, + crypto_aead_chacha20poly1305_ietf_NSECBYTES = 0, + + crypto_aead_xchacha20poly1305_ietf_ABYTES = 16, + crypto_aead_xchacha20poly1305_ietf_KEYBYTES = 32, + crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX = SODIUM_SIZE_MAX, + crypto_aead_xchacha20poly1305_ietf_NPUBBYTES = 24, + crypto_aead_xchacha20poly1305_ietf_NSECBYTES = 0, + + crypto_auth_hmacsha256_BYTES = 32, + crypto_auth_hmacsha256_KEYBYTES = 32, + crypto_auth_hmacsha512256_BYTES = 32, + crypto_auth_hmacsha512256_KEYBYTES = 32, + crypto_auth_hmacsha512_BYTES = 64, + crypto_auth_hmacsha512_KEYBYTES = 32, + + crypto_auth_BYTES = crypto_auth_hmacsha512256_BYTES, + crypto_auth_KEYBYTES = crypto_auth_hmacsha512256_KEYBYTES, + + crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32, + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES = 16, + crypto_box_curve25519xsalsa20poly1305_MACBYTES = 16, + crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX = SODIUM_SIZE_MAX, + crypto_box_curve25519xsalsa20poly1305_NONCEBYTES = 24, + crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32, + crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32, + crypto_box_curve25519xsalsa20poly1305_SEEDBYTES = 32, + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES = crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + crypto_box_curve25519xsalsa20poly1305_MACBYTES, + + crypto_box_BEFORENMBYTES = crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES, + crypto_box_BOXZEROBYTES = crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES, + crypto_box_MACBYTES = crypto_box_curve25519xsalsa20poly1305_MACBYTES, + crypto_box_MESSAGEBYTES_MAX = crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX, + crypto_box_NONCEBYTES = crypto_box_curve25519xsalsa20poly1305_NONCEBYTES, + crypto_box_PUBLICKEYBYTES = crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES, + crypto_box_SECRETKEYBYTES = crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES, + crypto_box_SEEDBYTES = crypto_box_curve25519xsalsa20poly1305_SEEDBYTES, + crypto_box_ZEROBYTES = crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, + + crypto_core_hchacha20_CONSTBYTES = 16, + crypto_core_hchacha20_INPUTBYTES = 16, + crypto_core_hchacha20_KEYBYTES = 32, + crypto_core_hchacha20_OUTPUTBYTES = 32, + + crypto_core_hsalsa20_CONSTBYTES = 16, + crypto_core_hsalsa20_INPUTBYTES = 16, + crypto_core_hsalsa20_KEYBYTES = 32, + crypto_core_hsalsa20_OUTPUTBYTES = 32, + + crypto_hash_sha256_BYTES = 32, + crypto_hash_sha512_BYTES = 64, + crypto_hash_BYTES = crypto_hash_sha512_BYTES, + + crypto_onetimeauth_poly1305_BYTES = 16, + crypto_onetimeauth_poly1305_KEYBYTES = 32, + crypto_onetimeauth_BYTES = crypto_onetimeauth_poly1305_BYTES, + crypto_onetimeauth_KEYBYTES = crypto_onetimeauth_poly1305_KEYBYTES, + + crypto_scalarmult_curve25519_BYTES = 32, + crypto_scalarmult_curve25519_SCALARBYTES = 32, + crypto_scalarmult_BYTES = crypto_scalarmult_curve25519_BYTES, + crypto_scalarmult_SCALARBYTES = crypto_scalarmult_curve25519_SCALARBYTES, + + crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES = 16, + crypto_secretbox_xsalsa20poly1305_KEYBYTES = 32, + crypto_secretbox_xsalsa20poly1305_MACBYTES = 16, + crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX = SODIUM_SIZE_MAX, + crypto_secretbox_xsalsa20poly1305_NONCEBYTES = 24, + crypto_secretbox_xsalsa20poly1305_ZEROBYTES = crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES + crypto_secretbox_xsalsa20poly1305_MACBYTES, + + crypto_secretbox_BOXZEROBYTES = crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES, + crypto_secretbox_KEYBYTES = crypto_secretbox_xsalsa20poly1305_KEYBYTES, + crypto_secretbox_MACBYTES = crypto_secretbox_xsalsa20poly1305_MACBYTES, + crypto_secretbox_MESSAGEBYTES_MAX = crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX, + crypto_secretbox_NONCEBYTES = crypto_secretbox_xsalsa20poly1305_NONCEBYTES, + crypto_secretbox_ZEROBYTES = crypto_secretbox_xsalsa20poly1305_ZEROBYTES, + + crypto_shorthash_siphash24_BYTES = 8, + crypto_shorthash_siphash24_KEYBYTES = 16, + crypto_shorthash_BYTES = crypto_shorthash_siphash24_BYTES, + crypto_shorthash_KEYBYTES = crypto_shorthash_siphash24_KEYBYTES, + + crypto_sign_ed25519_BYTES = 64, + crypto_sign_ed25519_MESSAGEBYTES_MAX = (SODIUM_SIZE_MAX - crypto_sign_ed25519_BYTES), + crypto_sign_ed25519_PUBLICKEYBYTES = 32, + crypto_sign_ed25519_SECRETKEYBYTES = (32 + 32), + crypto_sign_ed25519_SEEDBYTES = 32, + crypto_sign_BYTES = crypto_sign_ed25519_BYTES, + crypto_sign_MESSAGEBYTES_MAX = crypto_sign_ed25519_MESSAGEBYTES_MAX, + crypto_sign_PUBLICKEYBYTES = crypto_sign_ed25519_PUBLICKEYBYTES, + crypto_sign_SECRETKEYBYTES = crypto_sign_ed25519_SECRETKEYBYTES, + crypto_sign_SEEDBYTES = crypto_sign_ed25519_SEEDBYTES, + + crypto_stream_chacha20_KEYBYTES = 32, + crypto_stream_chacha20_MESSAGEBYTES_MAX = SODIUM_SIZE_MAX, + crypto_stream_chacha20_NONCEBYTES = 8, + crypto_stream_chacha20_ietf_KEYBYTES = 32, + crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX = SODIUM_SIZE_MAX, + crypto_stream_chacha20_ietf_NONCEBYTES = 12, + crypto_stream_salsa20_KEYBYTES = 32, + crypto_stream_salsa20_MESSAGEBYTES_MAX = SODIUM_SIZE_MAX, + crypto_stream_salsa20_NONCEBYTES = 8, + crypto_stream_xchacha20_KEYBYTES = 32, + crypto_stream_xchacha20_MESSAGEBYTES_MAX = SODIUM_SIZE_MAX, + crypto_stream_xchacha20_NONCEBYTES = 24, + crypto_stream_xsalsa20_KEYBYTES = 32, + crypto_stream_xsalsa20_MESSAGEBYTES_MAX = SODIUM_SIZE_MAX, + crypto_stream_xsalsa20_NONCEBYTES = 24, + crypto_stream_KEYBYTES = crypto_stream_xsalsa20_KEYBYTES, + crypto_stream_MESSAGEBYTES_MAX = crypto_stream_xsalsa20_MESSAGEBYTES_MAX, + crypto_stream_NONCEBYTES = crypto_stream_xsalsa20_NONCEBYTES, + + crypto_verify_16_BYTES = 16, + crypto_verify_32_BYTES = 32, + crypto_verify_64_BYTES = 64, + + randombytes_SEEDBYTES = 32, +}; + +inline const char* sodium_version_string() { return "Botan Sodium Compat"; } + +inline int sodium_library_version_major() { return 0; } + +inline int sodium_library_version_minor() { return 0; } + +inline int sodium_library_minimal() { return 0; } + +inline int sodium_init() { return 0; } + +// sodium/crypto_verify_{16,32,64}.h + +BOTAN_PUBLIC_API(2,11) +int crypto_verify_16(const uint8_t x[16], const uint8_t y[16]); + +BOTAN_PUBLIC_API(2,11) +int crypto_verify_32(const uint8_t x[32], const uint8_t y[32]); + +BOTAN_PUBLIC_API(2,11) +int crypto_verify_64(const uint8_t x[64], const uint8_t y[64]); + +// sodium/utils.h +BOTAN_PUBLIC_API(2,11) +void sodium_memzero(void* ptr, size_t len); + +BOTAN_PUBLIC_API(2,11) +int sodium_memcmp(const void* x, const void* y, size_t len); + +BOTAN_PUBLIC_API(2,11) +int sodium_compare(const uint8_t x[], const uint8_t y[], size_t len); + +BOTAN_PUBLIC_API(2,11) +int sodium_is_zero(const uint8_t nonce[], size_t nlen); + +BOTAN_PUBLIC_API(2,11) +void sodium_increment(uint8_t n[], size_t nlen); + +BOTAN_PUBLIC_API(2,11) +void sodium_add(uint8_t a[], const uint8_t b[], size_t len); + +BOTAN_PUBLIC_API(2,11) +void* sodium_malloc(size_t size); + +BOTAN_PUBLIC_API(2,11) +void* sodium_allocarray(size_t count, size_t size); + +BOTAN_PUBLIC_API(2,11) +void sodium_free(void* ptr); + +BOTAN_PUBLIC_API(2,11) +int sodium_mprotect_noaccess(void* ptr); + +BOTAN_PUBLIC_API(2,11) +int sodium_mprotect_readwrite(void* ptr); + +// sodium/randombytes.h + +inline size_t randombytes_seedbytes() { return randombytes_SEEDBYTES; } + +BOTAN_PUBLIC_API(2,11) +void randombytes_buf(void* buf, size_t size); + +BOTAN_PUBLIC_API(2,11) +void randombytes_buf_deterministic(void* buf, size_t size, + const uint8_t seed[32]); + +BOTAN_PUBLIC_API(2,11) +uint32_t randombytes_uniform(uint32_t upper_bound); + +inline uint32_t randombytes_random() + { + uint32_t x = 0; + randombytes_buf(&x, 4); + return x; + } + +inline void randombytes_stir() {} + +inline int randombytes_close() { return 0; } + +inline const char* randombytes_implementation_name() + { + return "botan"; + } + +inline void randombytes(uint8_t buf[], size_t buf_len) + { + return randombytes_buf(buf, buf_len); + } + +// sodium/crypto_secretbox_xsalsa20poly1305.h + +inline size_t crypto_secretbox_xsalsa20poly1305_keybytes() + { + return crypto_secretbox_xsalsa20poly1305_KEYBYTES; + } + +inline size_t crypto_secretbox_xsalsa20poly1305_noncebytes() + { + return crypto_secretbox_xsalsa20poly1305_NONCEBYTES; + } + +inline size_t crypto_secretbox_xsalsa20poly1305_macbytes() + { + return crypto_secretbox_xsalsa20poly1305_MACBYTES; + } + +inline size_t crypto_secretbox_xsalsa20poly1305_messagebytes_max() + { + return crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_secretbox_xsalsa20poly1305(uint8_t ctext[], + const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_secretbox_xsalsa20poly1305_open(uint8_t ptext[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t nonce[], + const uint8_t key[]); + +inline void crypto_secretbox_xsalsa20poly1305_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +inline size_t crypto_secretbox_xsalsa20poly1305_boxzerobytes() + { + return crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES; + } + +inline size_t crypto_secretbox_xsalsa20poly1305_zerobytes() + { + return crypto_secretbox_xsalsa20poly1305_ZEROBYTES; + } + +// sodium/crypto_secretbox.h + +inline size_t crypto_secretbox_keybytes() { return crypto_secretbox_KEYBYTES; } + +inline size_t crypto_secretbox_noncebytes() { return crypto_secretbox_NONCEBYTES; } + +inline size_t crypto_secretbox_macbytes() { return crypto_secretbox_MACBYTES; } + +inline size_t crypto_secretbox_messagebytes_max() { return crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX; } + +inline const char* crypto_secretbox_primitive() { return "xsalsa20poly1305"; } + +BOTAN_PUBLIC_API(2,11) +int crypto_secretbox_detached(uint8_t ctext[], uint8_t mac[], + const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_secretbox_open_detached(uint8_t ptext[], + const uint8_t ctext[], + const uint8_t mac[], + size_t ctext_len, + const uint8_t nonce[], + const uint8_t key[]); + +inline int crypto_secretbox_easy(uint8_t ctext[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_secretbox_detached(ctext + crypto_secretbox_MACBYTES, ctext, + ptext, ptext_len, nonce, key); + } + +inline int crypto_secretbox_open_easy(uint8_t out[], const uint8_t ctext[], size_t ctext_len, + const uint8_t nonce[], const uint8_t key[]) + { + if(ctext_len < crypto_secretbox_MACBYTES) + { + return -1; + } + + return crypto_secretbox_open_detached(out, ctext + crypto_secretbox_MACBYTES, + ctext, ctext_len - crypto_secretbox_MACBYTES, + nonce, key); + } + +inline void crypto_secretbox_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +inline size_t crypto_secretbox_zerobytes() + { + return crypto_secretbox_ZEROBYTES; + } + +inline size_t crypto_secretbox_boxzerobytes() + { + return crypto_secretbox_BOXZEROBYTES; + } + +inline int crypto_secretbox(uint8_t ctext[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_secretbox_xsalsa20poly1305(ctext, ptext, ptext_len, nonce, key); + } + +inline int crypto_secretbox_open(uint8_t ptext[], const uint8_t ctext[], + size_t ctext_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_secretbox_xsalsa20poly1305_open(ptext, ctext, ctext_len, nonce, key); + } + +// sodium/crypto_aead_xchacha20poly1305.h + +inline size_t crypto_aead_chacha20poly1305_ietf_keybytes() + { + return crypto_aead_chacha20poly1305_ietf_KEYBYTES; + } + +inline size_t crypto_aead_chacha20poly1305_ietf_nsecbytes() + { + return crypto_aead_chacha20poly1305_ietf_NSECBYTES; + } + +inline size_t crypto_aead_chacha20poly1305_ietf_npubbytes() + { + return crypto_aead_chacha20poly1305_ietf_NPUBBYTES; + } + +inline size_t crypto_aead_chacha20poly1305_ietf_abytes() + { + return crypto_aead_chacha20poly1305_ietf_ABYTES; + } + +inline size_t crypto_aead_chacha20poly1305_ietf_messagebytes_max() + { + return crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_chacha20poly1305_ietf_encrypt(uint8_t ctext[], + unsigned long long* ctext_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_chacha20poly1305_ietf_decrypt(uint8_t ptext[], + unsigned long long* ptext_len, + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_chacha20poly1305_ietf_encrypt_detached(uint8_t ctext[], + uint8_t mac[], + unsigned long long* mac_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_chacha20poly1305_ietf_decrypt_detached(uint8_t m[], + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t mac[], + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]); + +inline void crypto_aead_chacha20poly1305_ietf_keygen(uint8_t k[32]) + { + return randombytes_buf(k, crypto_aead_chacha20poly1305_ietf_KEYBYTES); + } + +inline size_t crypto_aead_chacha20poly1305_keybytes() + { + return crypto_aead_chacha20poly1305_KEYBYTES; + } + +inline size_t crypto_aead_chacha20poly1305_nsecbytes() + { + return crypto_aead_chacha20poly1305_NSECBYTES; + } + +inline size_t crypto_aead_chacha20poly1305_npubbytes() + { + return crypto_aead_chacha20poly1305_NPUBBYTES; + } + +inline size_t crypto_aead_chacha20poly1305_abytes() + { + return crypto_aead_chacha20poly1305_ABYTES; + } + +inline size_t crypto_aead_chacha20poly1305_messagebytes_max() + { + return crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_chacha20poly1305_encrypt(uint8_t ctext[], + unsigned long long* ctext_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_chacha20poly1305_decrypt(uint8_t m[], + unsigned long long* ptext_len, + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_chacha20poly1305_encrypt_detached(uint8_t ctext[], + uint8_t mac[], + unsigned long long* mac_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_chacha20poly1305_decrypt_detached(uint8_t m[], + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t mac[], + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]); + +inline void crypto_aead_chacha20poly1305_keygen(uint8_t k[32]) + { + randombytes_buf(k, 32); + } + +// sodium/crypto_aead_xchacha20poly1305.h + +inline size_t crypto_aead_xchacha20poly1305_ietf_keybytes() + { + return crypto_aead_xchacha20poly1305_ietf_KEYBYTES; + } + +inline size_t crypto_aead_xchacha20poly1305_ietf_nsecbytes() + { + return crypto_aead_xchacha20poly1305_ietf_NSECBYTES; + } + +inline size_t crypto_aead_xchacha20poly1305_ietf_npubbytes() + { + return crypto_aead_xchacha20poly1305_ietf_NPUBBYTES; + } + +inline size_t crypto_aead_xchacha20poly1305_ietf_abytes() + { + return crypto_aead_xchacha20poly1305_ietf_ABYTES; + } + +inline size_t crypto_aead_xchacha20poly1305_ietf_messagebytes_max() + { + return crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_xchacha20poly1305_ietf_encrypt(uint8_t ctext[], + unsigned long long* ctext_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_xchacha20poly1305_ietf_decrypt(uint8_t ptext[], + unsigned long long* ptext_len, + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_xchacha20poly1305_ietf_encrypt_detached(uint8_t ctext[], + uint8_t mac[], + unsigned long long* mac_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_aead_xchacha20poly1305_ietf_decrypt_detached(uint8_t ptext[], + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t mac[], + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]); + +inline void crypto_aead_xchacha20poly1305_ietf_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +// sodium/crypto_box_curve25519xsalsa20poly1305.h + +inline size_t crypto_box_curve25519xsalsa20poly1305_seedbytes() + { + return crypto_box_curve25519xsalsa20poly1305_SEEDBYTES; + } + +inline size_t crypto_box_curve25519xsalsa20poly1305_publickeybytes() + { + return crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES; + } + +inline size_t crypto_box_curve25519xsalsa20poly1305_secretkeybytes() + { + return crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES; + } + +inline size_t crypto_box_curve25519xsalsa20poly1305_beforenmbytes() + { + return crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES; + } + +inline size_t crypto_box_curve25519xsalsa20poly1305_noncebytes() + { + return crypto_box_curve25519xsalsa20poly1305_NONCEBYTES; + } + +inline size_t crypto_box_curve25519xsalsa20poly1305_macbytes() + { + return crypto_box_curve25519xsalsa20poly1305_MACBYTES; + } + +inline size_t crypto_box_curve25519xsalsa20poly1305_messagebytes_max() + { + return crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX; + } + +inline size_t crypto_box_curve25519xsalsa20poly1305_boxzerobytes() + { + return crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES; + } + +inline size_t crypto_box_curve25519xsalsa20poly1305_zerobytes() + { + return crypto_box_curve25519xsalsa20poly1305_ZEROBYTES; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_box_curve25519xsalsa20poly1305_seed_keypair(uint8_t pk[32], + uint8_t sk[32], + const uint8_t seed[32]); + +BOTAN_PUBLIC_API(2,11) +int crypto_box_curve25519xsalsa20poly1305_keypair(uint8_t pk[32], + uint8_t sk[32]); + +BOTAN_PUBLIC_API(2,11) +int crypto_box_curve25519xsalsa20poly1305_beforenm(uint8_t key[], + const uint8_t pk[32], + const uint8_t sk[32]); + +BOTAN_PUBLIC_API(2,11) +int crypto_box_curve25519xsalsa20poly1305(uint8_t ctext[], + const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], + const uint8_t pk[32], + const uint8_t sk[32]); + +BOTAN_PUBLIC_API(2,11) +int crypto_box_curve25519xsalsa20poly1305_open(uint8_t ptext[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t nonce[], + const uint8_t pk[32], + const uint8_t sk[32]); + +inline int crypto_box_curve25519xsalsa20poly1305_afternm(uint8_t ctext[], + const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_secretbox_xsalsa20poly1305(ctext, ptext, ptext_len, nonce, key); + } + +inline int crypto_box_curve25519xsalsa20poly1305_open_afternm(uint8_t ptext[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_secretbox_xsalsa20poly1305_open(ptext, ctext, ctext_len, nonce, key); + } + +// sodium/crypto_box.h + +inline size_t crypto_box_seedbytes() + { + return crypto_box_SEEDBYTES; + } + +inline size_t crypto_box_publickeybytes() + { + return crypto_box_PUBLICKEYBYTES; + } + +inline size_t crypto_box_secretkeybytes() + { + return crypto_box_SECRETKEYBYTES; + } + +inline size_t crypto_box_noncebytes() + { + return crypto_box_NONCEBYTES; + } + +inline size_t crypto_box_macbytes() + { + return crypto_box_MACBYTES; + } + +inline size_t crypto_box_messagebytes_max() + { + return crypto_box_MESSAGEBYTES_MAX; + } + +inline size_t crypto_box_beforenmbytes() + { + return crypto_box_BEFORENMBYTES; + } + +inline const char* crypto_box_primitive() { return "curve25519xsalsa20poly1305"; } + +inline int crypto_box_seed_keypair(uint8_t pk[32], uint8_t sk[32], + const uint8_t seed[]) + { + return crypto_box_curve25519xsalsa20poly1305_seed_keypair(pk, sk, seed); + } + +inline int crypto_box_keypair(uint8_t pk[32], uint8_t sk[32]) + { + return crypto_box_curve25519xsalsa20poly1305_keypair(pk, sk); + } + +BOTAN_PUBLIC_API(2,11) +int crypto_box_detached(uint8_t ctext[], uint8_t mac[], + const uint8_t ptext[], size_t ptext_len, + const uint8_t nonce[], const uint8_t pk[32], + const uint8_t sk[32]); + +BOTAN_PUBLIC_API(2,11) +int crypto_box_open_detached(uint8_t ptext[], const uint8_t ctext[], + const uint8_t mac[], + size_t ctext_len, + const uint8_t nonce[], + const uint8_t pk[32], + const uint8_t sk[32]); + +inline int crypto_box_easy(uint8_t ctext[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t pk[32], const uint8_t sk[32]) + { + return crypto_box_detached(ctext + crypto_box_MACBYTES, ctext, ptext, ptext_len, nonce, pk, sk); + } + +inline int crypto_box_open_easy(uint8_t ptext[], const uint8_t ctext[], + size_t ctext_len, const uint8_t nonce[], + const uint8_t pk[32], const uint8_t sk[32]) + { + if(ctext_len < crypto_box_MACBYTES) + { + return -1; + } + + return crypto_box_open_detached(ptext, ctext + crypto_box_MACBYTES, + ctext, ctext_len - crypto_box_MACBYTES, + nonce, pk, sk); + } + +inline int crypto_box_beforenm(uint8_t key[], const uint8_t pk[32], + const uint8_t sk[32]) + { + return crypto_box_curve25519xsalsa20poly1305_beforenm(key, pk, sk); + } + +inline int crypto_box_afternm(uint8_t ctext[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_box_curve25519xsalsa20poly1305_afternm(ctext, ptext, ptext_len, nonce, key); + } + +inline int crypto_box_open_afternm(uint8_t ptext[], const uint8_t ctext[], + size_t ctext_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_box_curve25519xsalsa20poly1305_open_afternm(ptext, ctext, ctext_len, nonce, key); + } + +inline int crypto_box_open_detached_afternm(uint8_t ptext[], const uint8_t ctext[], + const uint8_t mac[], + size_t ctext_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_secretbox_open_detached(ptext, ctext, mac, ctext_len, nonce, key); + } + +inline int crypto_box_open_easy_afternm(uint8_t ptext[], const uint8_t ctext[], + size_t ctext_len, const uint8_t nonce[], + const uint8_t key[]) + { + if(ctext_len < crypto_box_MACBYTES) + { + return -1; + } + + return crypto_box_open_detached_afternm(ptext, ctext + crypto_box_MACBYTES, + ctext, ctext_len - crypto_box_MACBYTES, + nonce, key); + } + +inline int crypto_box_detached_afternm(uint8_t ctext[], uint8_t mac[], + const uint8_t ptext[], size_t ptext_len, + const uint8_t nonce[], const uint8_t key[]) + { + return crypto_secretbox_detached(ctext, mac, ptext, ptext_len, nonce, key); + } + +inline int crypto_box_easy_afternm(uint8_t ctext[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_box_detached_afternm(ctext + crypto_box_MACBYTES, ctext, ptext, ptext_len, nonce, key); + } + +inline size_t crypto_box_zerobytes() { return crypto_box_ZEROBYTES; } + +inline size_t crypto_box_boxzerobytes() { return crypto_box_BOXZEROBYTES; } + +inline int crypto_box(uint8_t ctext[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t pk[32], const uint8_t sk[32]) + { + return crypto_box_curve25519xsalsa20poly1305(ctext, ptext, ptext_len, nonce, pk, sk); + } + +inline int crypto_box_open(uint8_t ptext[], const uint8_t ctext[], + size_t ctext_len, const uint8_t nonce[], + const uint8_t pk[32], const uint8_t sk[32]) + { + return crypto_box_curve25519xsalsa20poly1305_open(ptext, ctext, ctext_len, nonce, pk, sk); + } + +// sodium/crypto_hash_sha512.h + +inline size_t crypto_hash_sha512_bytes() { return crypto_hash_sha512_BYTES; } + +BOTAN_PUBLIC_API(2,11) +int crypto_hash_sha512(uint8_t out[64], const uint8_t in[], size_t in_len); + +// sodium/crypto_auth_hmacsha512.h + +inline size_t crypto_auth_hmacsha512_bytes() { return crypto_auth_hmacsha512_BYTES; } + +inline size_t crypto_auth_hmacsha512_keybytes() { return crypto_auth_hmacsha512_KEYBYTES; } + +BOTAN_PUBLIC_API(2,11) +int crypto_auth_hmacsha512(uint8_t out[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_auth_hmacsha512_verify(const uint8_t h[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]); + +inline void crypto_auth_hmacsha512_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +// sodium/crypto_auth_hmacsha512256.h + +inline size_t crypto_auth_hmacsha512256_bytes() + { + return crypto_auth_hmacsha512256_BYTES; + } + +inline size_t crypto_auth_hmacsha512256_keybytes() + { + return crypto_auth_hmacsha512256_KEYBYTES; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_auth_hmacsha512256(uint8_t out[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_auth_hmacsha512256_verify(const uint8_t h[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]); + +inline void crypto_auth_hmacsha512256_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +// sodium/crypto_auth.h + +inline size_t crypto_auth_bytes() { return crypto_auth_BYTES; } + +inline size_t crypto_auth_keybytes() { return crypto_auth_KEYBYTES; } + +inline const char* crypto_auth_primitive() { return "hmacsha512256"; } + +inline int crypto_auth(uint8_t out[], const uint8_t in[], + size_t in_len, const uint8_t key[]) + { + return crypto_auth_hmacsha512256(out, in, in_len, key); + } + +inline int crypto_auth_verify(const uint8_t mac[], const uint8_t in[], + size_t in_len, const uint8_t key[]) + { + return crypto_auth_hmacsha512256_verify(mac, in, in_len, key); + } + +inline void crypto_auth_keygen(uint8_t k[]) + { + return randombytes_buf(k, crypto_auth_KEYBYTES); + } + +// sodium/crypto_hash_sha256.h + +inline size_t crypto_hash_sha256_bytes() + { + return crypto_hash_sha256_BYTES; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_hash_sha256(uint8_t out[], const uint8_t in[], size_t in_len); + +// sodium/crypto_auth_hmacsha256.h + +inline size_t crypto_auth_hmacsha256_bytes() + { + return crypto_auth_hmacsha256_BYTES; + } + +inline size_t crypto_auth_hmacsha256_keybytes() + { + return crypto_auth_hmacsha256_KEYBYTES; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_auth_hmacsha256(uint8_t out[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_auth_hmacsha256_verify(const uint8_t h[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]); + +inline void crypto_auth_hmacsha256_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +// sodium/crypto_stream_xsalsa20.h + +inline size_t crypto_stream_xsalsa20_keybytes() + { + return crypto_stream_xsalsa20_KEYBYTES; + } + +inline size_t crypto_stream_xsalsa20_noncebytes() + { + return crypto_stream_xsalsa20_NONCEBYTES; + } + +inline size_t crypto_stream_xsalsa20_messagebytes_max() + { + return crypto_stream_xsalsa20_MESSAGEBYTES_MAX; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_xsalsa20(uint8_t out[], size_t ctext_len, + const uint8_t nonce[], const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_xsalsa20_xor(uint8_t out[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_xsalsa20_xor_ic(uint8_t out[], const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], uint64_t ic, + const uint8_t key[]); + +inline void crypto_stream_xsalsa20_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +// sodium/crypto_core_hsalsa20.h + +inline size_t crypto_core_hsalsa20_outputbytes() + { + return crypto_core_hsalsa20_OUTPUTBYTES; + } + +inline size_t crypto_core_hsalsa20_inputbytes() + { + return crypto_core_hsalsa20_INPUTBYTES; + } + +inline size_t crypto_core_hsalsa20_keybytes() + { + return crypto_core_hsalsa20_KEYBYTES; + } + +inline size_t crypto_core_hsalsa20_constbytes() + { + return crypto_core_hsalsa20_CONSTBYTES; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_core_hsalsa20(uint8_t out[], const uint8_t in[], + const uint8_t key[], const uint8_t c[]); + +// sodium/crypto_hash.h + +inline size_t crypto_hash_bytes() + { + return crypto_hash_BYTES; + } + +inline int crypto_hash(uint8_t out[], const uint8_t in[], size_t in_len) + { + return crypto_hash_sha512(out, in, in_len); + } + +inline const char* crypto_hash_primitive() { return "sha512"; } + +// sodium/crypto_onetimeauth_poly1305.h + +inline size_t crypto_onetimeauth_poly1305_bytes() + { + return crypto_onetimeauth_poly1305_BYTES; + } + +inline size_t crypto_onetimeauth_poly1305_keybytes() + { + return crypto_onetimeauth_poly1305_KEYBYTES; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_onetimeauth_poly1305(uint8_t out[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_onetimeauth_poly1305_verify(const uint8_t h[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]); + +inline void crypto_onetimeauth_poly1305_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +// sodium/crypto_onetimeauth.h + +inline size_t crypto_onetimeauth_bytes() { return crypto_onetimeauth_BYTES; } + +inline size_t crypto_onetimeauth_keybytes() { return crypto_onetimeauth_KEYBYTES; } + +inline const char* crypto_onetimeauth_primitive() { return "poly1305"; } + +inline int crypto_onetimeauth(uint8_t out[], const uint8_t in[], + size_t in_len, const uint8_t key[]) + { + return crypto_onetimeauth_poly1305(out, in, in_len, key); + } + +inline int crypto_onetimeauth_verify(const uint8_t h[], const uint8_t in[], + size_t in_len, const uint8_t key[]) + { + return crypto_onetimeauth_poly1305_verify(h, in, in_len, key); + } + +inline void crypto_onetimeauth_keygen(uint8_t k[32]) + { + return crypto_onetimeauth_poly1305_keygen(k); + } + +// sodium/crypto_scalarmult_curve25519.h + +inline size_t crypto_scalarmult_curve25519_bytes() + { + return crypto_scalarmult_curve25519_BYTES; + } + +inline size_t crypto_scalarmult_curve25519_scalarbytes() + { + return crypto_scalarmult_curve25519_SCALARBYTES; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_scalarmult_curve25519(uint8_t out[], const uint8_t scalar[], const uint8_t basepoint[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_scalarmult_curve25519_base(uint8_t out[], const uint8_t scalar[]); + +// sodium/crypto_scalarmult.h + +inline size_t crypto_scalarmult_bytes() { return crypto_scalarmult_curve25519_bytes(); } + +inline size_t crypto_scalarmult_scalarbytes() { return crypto_scalarmult_curve25519_scalarbytes(); } + +inline const char* crypto_scalarmult_primitive() { return "curve25519"; } + +inline int crypto_scalarmult_base(uint8_t out[], const uint8_t scalar[]) + { + return crypto_scalarmult_curve25519_base(out, scalar); + } + +inline int crypto_scalarmult(uint8_t out[], const uint8_t scalar[], const uint8_t base[]) + { + return crypto_scalarmult_curve25519(out, scalar, base); + } + +// sodium/crypto_stream_chacha20.h + +inline size_t crypto_stream_chacha20_keybytes() + { + return crypto_stream_chacha20_KEYBYTES; + } + +inline size_t crypto_stream_chacha20_noncebytes() + { + return crypto_stream_chacha20_NONCEBYTES; + } + +inline size_t crypto_stream_chacha20_messagebytes_max() + { + return crypto_stream_chacha20_MESSAGEBYTES_MAX; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_chacha20(uint8_t out[], size_t ctext_len, + const uint8_t nonce[], const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_chacha20_xor(uint8_t out[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_chacha20_xor_ic(uint8_t out[], const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], uint64_t ic, + const uint8_t key[]); + +inline void crypto_stream_chacha20_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +inline size_t crypto_stream_chacha20_ietf_keybytes() + { + return crypto_stream_chacha20_ietf_KEYBYTES; + } + +inline size_t crypto_stream_chacha20_ietf_noncebytes() + { + return crypto_stream_chacha20_ietf_NONCEBYTES; + } + +inline size_t crypto_stream_chacha20_ietf_messagebytes_max() + { + return crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_chacha20_ietf(uint8_t out[], size_t ctext_len, + const uint8_t nonce[], const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_chacha20_ietf_xor(uint8_t out[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_chacha20_ietf_xor_ic(uint8_t out[], const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], uint32_t ic, + const uint8_t key[]); + +inline void crypto_stream_chacha20_ietf_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +// sodium/crypto_stream_xchacha20.h + +inline size_t crypto_stream_xchacha20_keybytes() + { + return crypto_stream_xchacha20_KEYBYTES; + } + +inline size_t crypto_stream_xchacha20_noncebytes() + { + return crypto_stream_xchacha20_NONCEBYTES; + } + +inline size_t crypto_stream_xchacha20_messagebytes_max() + { + return crypto_stream_xchacha20_MESSAGEBYTES_MAX; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_xchacha20(uint8_t out[], size_t ctext_len, + const uint8_t nonce[], const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_xchacha20_xor(uint8_t out[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_xchacha20_xor_ic(uint8_t out[], const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], uint64_t ic, + const uint8_t key[]); + +inline void crypto_stream_xchacha20_keygen(uint8_t k[32]) + { + return randombytes_buf(k, crypto_stream_xchacha20_KEYBYTES); + } + +// sodium/crypto_stream_salsa20.h + +inline size_t crypto_stream_salsa20_keybytes() + { + return crypto_stream_xsalsa20_KEYBYTES; + } + +inline size_t crypto_stream_salsa20_noncebytes() + { + return crypto_stream_salsa20_NONCEBYTES; + } + +inline size_t crypto_stream_salsa20_messagebytes_max() + { + return crypto_stream_salsa20_MESSAGEBYTES_MAX; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_salsa20(uint8_t out[], size_t ctext_len, + const uint8_t nonce[], const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_salsa20_xor(uint8_t out[], const uint8_t ptext[], + size_t ptext_len, const uint8_t nonce[], + const uint8_t key[]); + +BOTAN_PUBLIC_API(2,11) +int crypto_stream_salsa20_xor_ic(uint8_t out[], const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], uint64_t ic, + const uint8_t key[]); + +inline void crypto_stream_salsa20_keygen(uint8_t k[32]) + { + return randombytes_buf(k, 32); + } + +// sodium/crypto_stream.h + +inline size_t crypto_stream_keybytes() { return crypto_stream_xsalsa20_keybytes(); } + +inline size_t crypto_stream_noncebytes() { return crypto_stream_xsalsa20_noncebytes(); } + +inline size_t crypto_stream_messagebytes_max() { return crypto_stream_MESSAGEBYTES_MAX; } + +inline const char* crypto_stream_primitive() { return "xsalsa20"; } + +inline int crypto_stream(uint8_t out[], size_t out_len, + const uint8_t nonce[24], const uint8_t key[32]) + { + return crypto_stream_xsalsa20(out, out_len, nonce, key); + } + +inline int crypto_stream_xor(uint8_t out[], const uint8_t in[], size_t in_len, + const uint8_t nonce[24], const uint8_t key[32]) + { + return crypto_stream_xsalsa20_xor(out, in, in_len, nonce, key); + } + +inline void crypto_stream_keygen(uint8_t key[32]) + { + return randombytes_buf(key, 32); + } + +// sodium/crypto_shorthash_siphash24.h + +inline size_t crypto_shorthash_siphash24_bytes() { return crypto_shorthash_siphash24_BYTES; } + +inline size_t crypto_shorthash_siphash24_keybytes() { return crypto_shorthash_siphash24_KEYBYTES; } + +BOTAN_PUBLIC_API(2,11) +int crypto_shorthash_siphash24(uint8_t out[8], const uint8_t in[], size_t in_len, const uint8_t key[16]); + +// sodium/crypto_shorthash.h + +inline size_t crypto_shorthash_bytes() { return crypto_shorthash_siphash24_bytes(); } + +inline size_t crypto_shorthash_keybytes() { return crypto_shorthash_siphash24_keybytes(); } + +inline const char* crypto_shorthash_primitive() { return "siphash24"; } + +inline int crypto_shorthash(uint8_t out[], const uint8_t in[], + size_t in_len, const uint8_t k[16]) + { + return crypto_shorthash_siphash24(out, in, in_len, k); + } + +inline void crypto_shorthash_keygen(uint8_t k[16]) + { + randombytes_buf(k, crypto_shorthash_siphash24_KEYBYTES); + } + +// sodium/crypto_sign_ed25519.h + +inline size_t crypto_sign_ed25519_bytes() + { + return crypto_sign_ed25519_BYTES; + } + +inline size_t crypto_sign_ed25519_seedbytes() + { + return crypto_sign_ed25519_SEEDBYTES; + } + +inline size_t crypto_sign_ed25519_publickeybytes() + { + return crypto_sign_ed25519_PUBLICKEYBYTES; + } + +inline size_t crypto_sign_ed25519_secretkeybytes() + { + return crypto_sign_ed25519_SECRETKEYBYTES; + } + +inline size_t crypto_sign_ed25519_messagebytes_max() + { + return crypto_sign_ed25519_MESSAGEBYTES_MAX; + } + +BOTAN_PUBLIC_API(2,11) +int crypto_sign_ed25519_detached(uint8_t sig[], + unsigned long long* sig_len, + const uint8_t msg[], + size_t msg_len, + const uint8_t sk[32]); + +BOTAN_PUBLIC_API(2,11) +int crypto_sign_ed25519_verify_detached(const uint8_t sig[], + const uint8_t msg[], + size_t msg_len, + const uint8_t pk[32]); + +BOTAN_PUBLIC_API(2,11) +int crypto_sign_ed25519_keypair(uint8_t pk[32], uint8_t sk[64]); + +BOTAN_PUBLIC_API(2,11) +int crypto_sign_ed25519_seed_keypair(uint8_t pk[32], uint8_t sk[64], + const uint8_t seed[]); + +// sodium/crypto_sign.h + +inline size_t crypto_sign_bytes() + { + return crypto_sign_BYTES; + } + +inline size_t crypto_sign_seedbytes() + { + return crypto_sign_SEEDBYTES; + } + +inline size_t crypto_sign_publickeybytes() + { + return crypto_sign_PUBLICKEYBYTES; + } + +inline size_t crypto_sign_secretkeybytes() + { + return crypto_sign_SECRETKEYBYTES; + } + +inline size_t crypto_sign_messagebytes_max() + { + return crypto_sign_MESSAGEBYTES_MAX; + } + +inline const char* crypto_sign_primitive() + { + return "ed25519"; + } + +inline int crypto_sign_seed_keypair(uint8_t pk[32], uint8_t sk[32], + const uint8_t seed[]) + { + return crypto_sign_ed25519_seed_keypair(pk, sk, seed); + } + +inline int crypto_sign_keypair(uint8_t pk[32], uint8_t sk[32]) + { + return crypto_sign_ed25519_keypair(pk, sk); + } + +inline int crypto_sign_detached(uint8_t sig[], unsigned long long* sig_len, + const uint8_t msg[], size_t msg_len, + const uint8_t sk[32]) + { + return crypto_sign_ed25519_detached(sig, sig_len, msg, msg_len, sk); + } + +inline int crypto_sign_verify_detached(const uint8_t sig[], + const uint8_t in[], + size_t in_len, + const uint8_t pk[32]) + { + return crypto_sign_ed25519_verify_detached(sig, in, in_len, pk); + } + +} + +} + +#endif diff --git a/src/lib/compat/sodium/sodium_25519.cpp b/src/lib/compat/sodium/sodium_25519.cpp new file mode 100644 index 000000000..1d520d7a3 --- /dev/null +++ b/src/lib/compat/sodium/sodium_25519.cpp @@ -0,0 +1,60 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/sodium.h> +#include <botan/ed25519.h> +#include <botan/curve25519.h> + +namespace Botan { + +int Sodium::crypto_scalarmult_curve25519(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]) + { + curve25519_donna(out, scalar, point); + return 0; + } + +int Sodium::crypto_scalarmult_curve25519_base(uint8_t out[32], const uint8_t scalar[32]) + { + curve25519_basepoint(out, scalar); + return 0; + } +int Sodium::crypto_sign_ed25519_detached(uint8_t sig[], + unsigned long long* sig_len, + const uint8_t msg[], + size_t msg_len, + const uint8_t sk[32]) + { + ed25519_sign(sig, msg, msg_len, sk); + + if(sig_len) + *sig_len = 64; + return 0; + } + +int Sodium::crypto_sign_ed25519_verify_detached(const uint8_t sig[64], + const uint8_t msg[], + size_t msg_len, + const uint8_t pk[32]) + { + const bool ok = ed25519_verify(msg, msg_len, sig, pk); + return ok ? 0 : -1; + } + +int Sodium::crypto_sign_ed25519_keypair(uint8_t pk[32], uint8_t sk[64]) + { + secure_vector<uint8_t> seed(32); + randombytes_buf(seed.data(), seed.size()); + return crypto_sign_ed25519_seed_keypair(pk, sk, seed.data()); + } + +int Sodium::crypto_sign_ed25519_seed_keypair(uint8_t pk[32], uint8_t sk[64], + const uint8_t seed[32]) + { + ed25519_gen_keypair(pk, sk, seed); + return 0; + } + +} diff --git a/src/lib/compat/sodium/sodium_aead.cpp b/src/lib/compat/sodium/sodium_aead.cpp new file mode 100644 index 000000000..f81154e73 --- /dev/null +++ b/src/lib/compat/sodium/sodium_aead.cpp @@ -0,0 +1,359 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/sodium.h> +#include <botan/aead.h> + +namespace Botan { + +namespace { + +int sodium_aead_chacha20poly1305_encrypt(uint8_t ctext[], + unsigned long long* ctext_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + size_t nonce_len, + const uint8_t key[]) + { + auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", ENCRYPTION); + + chacha20poly1305->set_key(key, 32); + chacha20poly1305->set_associated_data(ad, ad_len); + chacha20poly1305->start(nonce, nonce_len); + + // FIXME do this in-place + secure_vector<uint8_t> buf; + buf.reserve(ptext_len + 16); + buf.assign(ptext, ptext + ptext_len); + + chacha20poly1305->finish(buf); + + copy_mem(ctext, buf.data(), buf.size()); + if(ctext_len) + *ctext_len = buf.size(); + return 0; + } + +int sodium_aead_chacha20poly1305_decrypt(uint8_t ptext[], + unsigned long long* ptext_len, + const uint8_t ctext[], + size_t ctext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + size_t nonce_len, + const uint8_t key[]) + { + if(ctext_len < 16) + return -1; + + *ptext_len = 0; + + auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", DECRYPTION); + + chacha20poly1305->set_key(key, 32); + chacha20poly1305->set_associated_data(ad, ad_len); + chacha20poly1305->start(nonce, nonce_len); + + // FIXME do this in-place + secure_vector<uint8_t> buf; + buf.assign(ctext, ctext + ctext_len); + + try + { + chacha20poly1305->finish(buf); + } + catch(Invalid_Authentication_Tag&) + { + return -1; + } + + *ptext_len = ctext_len - 16; + + copy_mem(ptext, buf.data(), buf.size()); + return 0; + } + +int sodium_aead_chacha20poly1305_encrypt_detached(uint8_t ctext[], + uint8_t mac[], + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + size_t nonce_len, + const uint8_t key[]) + { + auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", ENCRYPTION); + + chacha20poly1305->set_key(key, 32); + chacha20poly1305->set_associated_data(ad, ad_len); + chacha20poly1305->start(nonce, nonce_len); + + // FIXME do this in-place + secure_vector<uint8_t> buf; + buf.reserve(ptext_len + 16); + buf.assign(ptext, ptext + ptext_len); + + chacha20poly1305->finish(buf); + + copy_mem(ctext, buf.data(), ptext_len); + copy_mem(mac, buf.data() + ptext_len, 16); + return 0; + } + +int sodium_aead_chacha20poly1305_decrypt_detached(uint8_t ptext[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t mac[], + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + size_t nonce_len, + const uint8_t key[]) + { + auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", DECRYPTION); + + chacha20poly1305->set_key(key, 32); + chacha20poly1305->set_associated_data(ad, ad_len); + chacha20poly1305->start(nonce, nonce_len); + + // FIXME do this in-place + secure_vector<uint8_t> buf; + buf.reserve(ctext_len + 16); + buf.assign(ctext, ctext + ctext_len); + buf.insert(buf.end(), mac, mac + 16); + + try + { + chacha20poly1305->finish(buf); + } + catch(Invalid_Authentication_Tag&) + { + return -1; + } + + copy_mem(ptext, buf.data(), buf.size()); + return 0; + } + +} + +int Sodium::crypto_aead_chacha20poly1305_ietf_encrypt(uint8_t ctext[], + unsigned long long* ctext_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t* unused_secret_nonce, + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + + return sodium_aead_chacha20poly1305_encrypt( + ctext, ctext_len, ptext, ptext_len, + ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key); + } + +int Sodium::crypto_aead_chacha20poly1305_ietf_decrypt(uint8_t ptext[], + unsigned long long* ptext_len, + uint8_t* unused_secret_nonce, + const uint8_t ctext[], + size_t ctext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + + return sodium_aead_chacha20poly1305_decrypt( + ptext, ptext_len, ctext, ctext_len, + ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key); + } + +int Sodium::crypto_aead_chacha20poly1305_ietf_encrypt_detached(uint8_t ctext[], + uint8_t mac[], + unsigned long long* mac_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + + if(mac_len) + *mac_len = 16; + + return sodium_aead_chacha20poly1305_encrypt_detached( + ctext, mac, ptext, ptext_len, + ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key); + } + +int Sodium::crypto_aead_chacha20poly1305_ietf_decrypt_detached(uint8_t ptext[], + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t mac[], + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + + return sodium_aead_chacha20poly1305_decrypt_detached( + ptext, ctext, ctext_len, mac, + ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key); + } + +int Sodium::crypto_aead_chacha20poly1305_encrypt(uint8_t ctext[], + unsigned long long* ctext_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + return sodium_aead_chacha20poly1305_encrypt( + ctext, ctext_len, ptext, ptext_len, + ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key); + } + +int Sodium::crypto_aead_chacha20poly1305_decrypt(uint8_t ptext[], + unsigned long long* ptext_len, + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + return sodium_aead_chacha20poly1305_decrypt( + ptext, ptext_len, ctext, ctext_len, + ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key); + } + +int Sodium::crypto_aead_chacha20poly1305_encrypt_detached(uint8_t ctext[], + uint8_t mac[], + unsigned long long* mac_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + if(mac_len) + *mac_len = 16; + + return sodium_aead_chacha20poly1305_encrypt_detached( + ctext, mac, ptext, ptext_len, + ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key); + } + +int Sodium::crypto_aead_chacha20poly1305_decrypt_detached(uint8_t ptext[], + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t mac[], + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + + return sodium_aead_chacha20poly1305_decrypt_detached( + ptext, ctext, ctext_len, mac, + ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key); + } + +int Sodium::crypto_aead_xchacha20poly1305_ietf_encrypt(uint8_t ctext[], + unsigned long long* ctext_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + + return sodium_aead_chacha20poly1305_encrypt( + ctext, ctext_len, ptext, ptext_len, + ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key); + } + +int Sodium::crypto_aead_xchacha20poly1305_ietf_decrypt(uint8_t ptext[], + unsigned long long* ptext_len, + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + + return sodium_aead_chacha20poly1305_decrypt( + ptext, ptext_len, ctext, ctext_len, + ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key); + } + +int Sodium::crypto_aead_xchacha20poly1305_ietf_encrypt_detached(uint8_t ctext[], + uint8_t mac[], + unsigned long long* mac_len, + const uint8_t ptext[], + size_t ptext_len, + const uint8_t ad[], + size_t ad_len, + const uint8_t unused_secret_nonce[], + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + if(mac_len) + *mac_len = 16; + + return sodium_aead_chacha20poly1305_encrypt_detached( + ctext, mac, ptext, ptext_len, + ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key); + } + +int Sodium::crypto_aead_xchacha20poly1305_ietf_decrypt_detached(uint8_t ptext[], + uint8_t unused_secret_nonce[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t mac[], + const uint8_t ad[], + size_t ad_len, + const uint8_t nonce[], + const uint8_t key[]) + { + BOTAN_UNUSED(unused_secret_nonce); + return sodium_aead_chacha20poly1305_decrypt_detached( + ptext, ctext, ctext_len, mac, + ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key); + } + +} diff --git a/src/lib/compat/sodium/sodium_auth.cpp b/src/lib/compat/sodium/sodium_auth.cpp new file mode 100644 index 000000000..747b8af33 --- /dev/null +++ b/src/lib/compat/sodium/sodium_auth.cpp @@ -0,0 +1,131 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/sodium.h> +#include <botan/mac.h> +#include <botan/hash.h> + +namespace Botan { + +int Sodium::crypto_hash_sha512(uint8_t out[64], const uint8_t in[], size_t in_len) + { + auto sha512 = HashFunction::create_or_throw("SHA-512"); + sha512->update(in, in_len); + sha512->final(out); + return 0; + } + +int Sodium::crypto_hash_sha256(uint8_t out[], const uint8_t in[], size_t in_len) + { + auto sha256 = HashFunction::create_or_throw("SHA-256"); + sha256->update(in, in_len); + sha256->final(out); + return 0; + } + +int Sodium::crypto_shorthash_siphash24(uint8_t out[8], const uint8_t in[], + size_t in_len, const uint8_t key[16]) + { + auto mac = MessageAuthenticationCode::create_or_throw("SipHash(2,4)"); + mac->set_key(key, crypto_shorthash_siphash24_KEYBYTES); + mac->update(in, in_len); + mac->final(out); + return 0; + } + +int Sodium::crypto_onetimeauth_poly1305(uint8_t out[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]) + { + auto mac = MessageAuthenticationCode::create_or_throw("Poly1305"); + mac->set_key(key, crypto_onetimeauth_poly1305_KEYBYTES); + mac->update(in, in_len); + mac->final(out); + return 0; + } + +int Sodium::crypto_onetimeauth_poly1305_verify(const uint8_t mac[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]) + { + secure_vector<uint8_t> computed(crypto_onetimeauth_poly1305_BYTES); + crypto_onetimeauth_poly1305(computed.data(), in, in_len, key); + return crypto_verify_16(computed.data(), mac) ? 0 : -1; + } + +int Sodium::crypto_auth_hmacsha512(uint8_t out[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]) + { + auto mac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-512)"); + mac->set_key(key, crypto_auth_hmacsha512_KEYBYTES); + mac->update(in, in_len); + mac->final(out); + return 0; + } + +int Sodium::crypto_auth_hmacsha512_verify(const uint8_t mac[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]) + { + secure_vector<uint8_t> computed(crypto_auth_hmacsha512_BYTES); + crypto_auth_hmacsha512(computed.data(), in, in_len, key); + return crypto_verify_64(computed.data(), mac) ? 0 : -1; + } + +int Sodium::crypto_auth_hmacsha512256(uint8_t out[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]) + { + auto mac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-512)"); + mac->set_key(key, crypto_auth_hmacsha512256_KEYBYTES); + mac->update(in, in_len); + + secure_vector<uint8_t> buf(64); + mac->final(buf); + + copy_mem(out, buf.data(), crypto_auth_hmacsha512256_BYTES); + return 0; + } + +int Sodium::crypto_auth_hmacsha512256_verify(const uint8_t mac[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]) + { + secure_vector<uint8_t> computed(crypto_auth_hmacsha512256_BYTES); + crypto_auth_hmacsha512256(computed.data(), in, in_len, key); + return crypto_verify_32(computed.data(), mac) ? 0 : -1; + } + +int Sodium::crypto_auth_hmacsha256(uint8_t out[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]) + { + auto mac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); + mac->set_key(key, crypto_auth_hmacsha256_KEYBYTES); + mac->update(in, in_len); + mac->final(out); + return 0; + } + +int Sodium::crypto_auth_hmacsha256_verify(const uint8_t mac[], + const uint8_t in[], + size_t in_len, + const uint8_t key[]) + { + secure_vector<uint8_t> computed(crypto_auth_hmacsha256_BYTES); + crypto_auth_hmacsha256(computed.data(), in, in_len, key); + return crypto_verify_32(computed.data(), mac) ? 0 : -1; + } + +} diff --git a/src/lib/compat/sodium/sodium_box.cpp b/src/lib/compat/sodium/sodium_box.cpp new file mode 100644 index 000000000..52b9a0303 --- /dev/null +++ b/src/lib/compat/sodium/sodium_box.cpp @@ -0,0 +1,100 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/sodium.h> +#include <botan/secmem.h> + +namespace Botan { + +int Sodium::crypto_box_curve25519xsalsa20poly1305_seed_keypair(uint8_t pk[32], + uint8_t sk[32], + const uint8_t seed[32]) + { + secure_vector<uint8_t> digest(64); + crypto_hash_sha512(digest.data(), seed, 32); + copy_mem(sk, digest.data(), 32); + return crypto_scalarmult_curve25519_base(pk, sk); + } + +int Sodium::crypto_box_curve25519xsalsa20poly1305_keypair(uint8_t pk[32], + uint8_t sk[32]) + { + randombytes_buf(sk, 32); + return crypto_scalarmult_curve25519_base(pk, sk); + } + +int Sodium::crypto_box_curve25519xsalsa20poly1305_beforenm(uint8_t key[], + const uint8_t pk[32], + const uint8_t sk[32]) + { + const uint8_t zero[16] = { 0 }; + secure_vector<uint8_t> shared(32); + + if(crypto_scalarmult_curve25519(shared.data(), sk, pk) != 0) + return -1; + + return crypto_core_hsalsa20(key, zero, shared.data(), nullptr); + } + +int Sodium::crypto_box_curve25519xsalsa20poly1305(uint8_t ctext[], + const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], + const uint8_t pk[32], + const uint8_t sk[32]) + { + secure_vector<uint8_t> shared(32); + + if(crypto_box_curve25519xsalsa20poly1305_beforenm(shared.data(), pk, sk) != 0) + return -1; + + return crypto_box_curve25519xsalsa20poly1305_afternm(ctext, ptext, ptext_len, nonce, shared.data()); + } + +int Sodium::crypto_box_curve25519xsalsa20poly1305_open(uint8_t ptext[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t nonce[], + const uint8_t pk[32], + const uint8_t sk[32]) + { + secure_vector<uint8_t> shared(32); + + if(crypto_box_curve25519xsalsa20poly1305_beforenm(shared.data(), pk, sk) != 0) + return -1; + + return crypto_box_curve25519xsalsa20poly1305_open_afternm(ptext, ctext, ctext_len, nonce, shared.data()); + } + +int Sodium::crypto_box_detached(uint8_t ctext[], uint8_t mac[], + const uint8_t ptext[], size_t ptext_len, + const uint8_t nonce[], const uint8_t pk[32], + const uint8_t sk[32]) + { + secure_vector<uint8_t> shared(32); + + if(crypto_box_beforenm(shared.data(), pk, sk) != 0) + return -1; + + return crypto_box_detached_afternm(ctext, mac, ptext, ptext_len, nonce, shared.data()); + } + +int Sodium::crypto_box_open_detached(uint8_t ptext[], const uint8_t ctext[], + const uint8_t mac[], + size_t ctext_len, + const uint8_t nonce[], + const uint8_t pk[32], + const uint8_t sk[32]) + { + secure_vector<uint8_t> shared(32); + + if(crypto_box_beforenm(shared.data(), pk, sk) != 0) + return -1; + + return crypto_box_open_detached_afternm(ptext, ctext, mac, ctext_len, nonce, shared.data()); + } + +} diff --git a/src/lib/compat/sodium/sodium_chacha.cpp b/src/lib/compat/sodium/sodium_chacha.cpp new file mode 100644 index 000000000..fed7a52f6 --- /dev/null +++ b/src/lib/compat/sodium/sodium_chacha.cpp @@ -0,0 +1,109 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/sodium.h> +#include <botan/stream_cipher.h> + +namespace Botan { + +int Sodium::crypto_stream_chacha20(uint8_t out[], size_t out_len, + const uint8_t nonce[], const uint8_t key[]) + { + auto chacha = StreamCipher::create_or_throw("ChaCha(20)"); + chacha->set_key(key, crypto_stream_chacha20_KEYBYTES); + chacha->set_iv(nonce, crypto_stream_chacha20_NONCEBYTES); + chacha->write_keystream(out, out_len); + return 0; + } + +int Sodium::crypto_stream_chacha20_xor(uint8_t out[], const uint8_t in[], + size_t in_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_stream_chacha20_xor_ic(out, in, in_len, nonce, 0, key); + } + +int Sodium::crypto_stream_chacha20_xor_ic(uint8_t out[], const uint8_t in[], + size_t in_len, + const uint8_t nonce[], uint64_t ic, + const uint8_t key[]) + { + if((ic >> 6) != 0) // otherwise multiply overflows + return -1; + + auto chacha = StreamCipher::create_or_throw("ChaCha(20)"); + chacha->set_key(key, crypto_stream_chacha20_KEYBYTES); + chacha->set_iv(nonce, crypto_stream_chacha20_NONCEBYTES); + chacha->seek(ic * 64); + chacha->cipher(in, out, in_len); + return 0; + } + +int Sodium::crypto_stream_chacha20_ietf(uint8_t out[], size_t out_len, + const uint8_t nonce[], const uint8_t key[]) + { + auto chacha = StreamCipher::create_or_throw("ChaCha(20)"); + chacha->set_key(key, crypto_stream_chacha20_ietf_KEYBYTES); + chacha->set_iv(nonce, crypto_stream_chacha20_ietf_NONCEBYTES); + chacha->write_keystream(out, out_len); + return 0; + } + +int Sodium::crypto_stream_chacha20_ietf_xor(uint8_t out[], + const uint8_t in[], size_t in_len, + const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_stream_chacha20_ietf_xor_ic(out, in, in_len, nonce, 0, key); + } + +int Sodium::crypto_stream_chacha20_ietf_xor_ic(uint8_t out[], + const uint8_t in[], size_t in_len, + const uint8_t nonce[], uint32_t ic, + const uint8_t key[]) + { + auto chacha = StreamCipher::create_or_throw("ChaCha(20)"); + chacha->set_key(key, crypto_stream_chacha20_ietf_KEYBYTES); + chacha->set_iv(nonce, crypto_stream_chacha20_ietf_NONCEBYTES); + chacha->seek(static_cast<uint64_t>(ic) * 64); + chacha->cipher(in, out, in_len); + return 0; + } + +int Sodium::crypto_stream_xchacha20(uint8_t out[], size_t out_len, + const uint8_t nonce[], const uint8_t key[]) + { + auto chacha = StreamCipher::create_or_throw("ChaCha(20)"); + chacha->set_key(key, crypto_stream_xchacha20_KEYBYTES); + chacha->set_iv(nonce, crypto_stream_xchacha20_NONCEBYTES); + chacha->write_keystream(out, out_len); + return 0; + } + +int Sodium::crypto_stream_xchacha20_xor(uint8_t out[], const uint8_t in[], + size_t in_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_stream_xchacha20_xor_ic(out, in, in_len, nonce, 0, key); + } + +int Sodium::crypto_stream_xchacha20_xor_ic(uint8_t out[], const uint8_t in[], + size_t in_len, + const uint8_t nonce[], uint64_t ic, + const uint8_t key[]) + { + if((ic >> 6) != 0) // otherwise multiply overflows + return -1; + + auto chacha = StreamCipher::create_or_throw("ChaCha(20)"); + chacha->set_key(key, crypto_stream_xchacha20_KEYBYTES); + chacha->set_iv(nonce, crypto_stream_xchacha20_NONCEBYTES); + chacha->seek(ic * 64); + chacha->cipher(in, out, in_len); + return 0; + } + +} diff --git a/src/lib/compat/sodium/sodium_salsa.cpp b/src/lib/compat/sodium/sodium_salsa.cpp new file mode 100644 index 000000000..c1465a9bb --- /dev/null +++ b/src/lib/compat/sodium/sodium_salsa.cpp @@ -0,0 +1,124 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/sodium.h> +#include <botan/salsa20.h> +#include <botan/loadstor.h> + +namespace Botan { + +int Sodium::crypto_core_hsalsa20(uint8_t out[], const uint8_t in[], + const uint8_t key[], const uint8_t c[]) + { + uint32_t in32[16] = { 0 }; + + static const uint32_t SIGMA[] = + { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 }; + + if(c == nullptr) + { + in32[0] = SIGMA[0]; + in32[5] = SIGMA[1]; + in32[10] = SIGMA[2]; + in32[15] = SIGMA[3]; + } + else + { + in32[0] = load_le<uint32_t>(c, 0); + in32[5] = load_le<uint32_t>(c, 1); + in32[10] = load_le<uint32_t>(c, 2); + in32[15] = load_le<uint32_t>(c, 3); + } + + in32[1] = load_le<uint32_t>(key, 0); + in32[2] = load_le<uint32_t>(key, 1); + in32[3] = load_le<uint32_t>(key, 2); + in32[4] = load_le<uint32_t>(key, 3); + + in32[6] = load_le<uint32_t>(in, 0); + in32[7] = load_le<uint32_t>(in, 1); + in32[8] = load_le<uint32_t>(in, 2); + in32[9] = load_le<uint32_t>(in, 3); + + in32[11] = load_le<uint32_t>(key, 4); + in32[12] = load_le<uint32_t>(key, 5); + in32[13] = load_le<uint32_t>(key, 6); + in32[14] = load_le<uint32_t>(key, 7); + + uint32_t out32[8] = { 0 }; + Salsa20::hsalsa20(out32, in32); + + copy_out_le(out, 32, out32); + return 0; + } + +int Sodium::crypto_stream_salsa20(uint8_t out[], size_t out_len, + const uint8_t nonce[], const uint8_t key[]) + { + Salsa20 salsa; + salsa.set_key(key, crypto_stream_salsa20_KEYBYTES); + salsa.set_iv(nonce, crypto_stream_salsa20_NONCEBYTES); + salsa.write_keystream(out, out_len); + return 0; + } + +int Sodium::crypto_stream_salsa20_xor(uint8_t out[], const uint8_t in[], + size_t in_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_stream_salsa20_xor_ic(out, in, in_len, nonce, 0, key); + } + +int Sodium::crypto_stream_salsa20_xor_ic(uint8_t out[], const uint8_t in[], + size_t in_len, + const uint8_t nonce[], uint64_t ic, + const uint8_t key[]) + { + if((ic >> 6) != 0) // otherwise multiply overflows + return -1; + + Salsa20 salsa; + salsa.set_key(key, crypto_stream_salsa20_KEYBYTES); + salsa.set_iv(nonce, crypto_stream_salsa20_NONCEBYTES); + salsa.seek(ic * 64); + salsa.cipher(in, out, in_len); + return 0; + } + +int Sodium::crypto_stream_xsalsa20(uint8_t out[], size_t out_len, + const uint8_t nonce[], const uint8_t key[]) + { + Salsa20 salsa; + salsa.set_key(key, crypto_stream_xsalsa20_KEYBYTES); + salsa.set_iv(nonce, crypto_stream_xsalsa20_NONCEBYTES); + salsa.write_keystream(out, out_len); + return 0; + } + +int Sodium::crypto_stream_xsalsa20_xor(uint8_t out[], const uint8_t in[], + size_t in_len, const uint8_t nonce[], + const uint8_t key[]) + { + return crypto_stream_xsalsa20_xor_ic(out, in, in_len, nonce, 0, key); + } + +int Sodium::crypto_stream_xsalsa20_xor_ic(uint8_t out[], const uint8_t in[], + size_t in_len, + const uint8_t nonce[], uint64_t ic, + const uint8_t key[]) + { + if((ic >> 6) != 0) // otherwise multiply overflows + return -1; + + Salsa20 salsa; + salsa.set_key(key, crypto_stream_xsalsa20_KEYBYTES); + salsa.set_iv(nonce, crypto_stream_xsalsa20_NONCEBYTES); + salsa.seek(ic * 64); + salsa.cipher(in, out, in_len); + return 0; + } + +} diff --git a/src/lib/compat/sodium/sodium_secretbox.cpp b/src/lib/compat/sodium/sodium_secretbox.cpp new file mode 100644 index 000000000..255e0631b --- /dev/null +++ b/src/lib/compat/sodium/sodium_secretbox.cpp @@ -0,0 +1,123 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/sodium.h> +#include <botan/secmem.h> +#include <botan/stream_cipher.h> +#include <botan/mac.h> + +namespace Botan { + +int Sodium::crypto_secretbox_xsalsa20poly1305(uint8_t ctext[], + const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], + const uint8_t key[]) + { + if(ptext_len < 32) + return -1; + + auto salsa = StreamCipher::create_or_throw("Salsa20"); + salsa->set_key(key, crypto_secretbox_KEYBYTES); + salsa->set_iv(nonce, crypto_secretbox_NONCEBYTES); + + secure_vector<uint8_t> auth_key(32); + salsa->write_keystream(auth_key.data(), auth_key.size()); + + salsa->cipher(ptext + 32, ctext + 32, ptext_len - 32); + + auto poly1305 = MessageAuthenticationCode::create_or_throw("Poly1305"); + poly1305->set_key(auth_key); + poly1305->update(ctext + 32, ptext_len - 32); + poly1305->final(ctext + 16); + + clear_mem(ctext, 16); + return 0; + } + +int Sodium::crypto_secretbox_xsalsa20poly1305_open(uint8_t ptext[], + const uint8_t ctext[], + size_t ctext_len, + const uint8_t nonce[], + const uint8_t key[]) + { + if(ctext_len < crypto_box_curve25519xsalsa20poly1305_ZEROBYTES) + { + return -1; + } + + auto salsa = StreamCipher::create_or_throw("Salsa20"); + salsa->set_key(key, crypto_secretbox_KEYBYTES); + salsa->set_iv(nonce, crypto_secretbox_NONCEBYTES); + + secure_vector<uint8_t> auth_key(32); + salsa->write_keystream(auth_key.data(), auth_key.size()); + + auto poly1305 = MessageAuthenticationCode::create_or_throw("Poly1305"); + poly1305->set_key(auth_key); + poly1305->update(ctext + 32, ctext_len - 32); + secure_vector<uint8_t> computed = poly1305->final(); + + if(!constant_time_compare(computed.data(), ctext + 16, 16)) + return -1; + + salsa->cipher(ctext + 32, ptext + 32, ctext_len - 32); + + clear_mem(ptext, 32); + return 0; + } + +int Sodium::crypto_secretbox_detached(uint8_t ctext[], uint8_t mac[], + const uint8_t ptext[], + size_t ptext_len, + const uint8_t nonce[], + const uint8_t key[]) + { + auto salsa = StreamCipher::create_or_throw("Salsa20"); + salsa->set_key(key, crypto_secretbox_KEYBYTES); + salsa->set_iv(nonce, crypto_secretbox_NONCEBYTES); + + secure_vector<uint8_t> auth_key(32); + salsa->write_keystream(auth_key.data(), auth_key.size()); + + salsa->cipher(ptext, ctext, ptext_len); + + auto poly1305 = MessageAuthenticationCode::create_or_throw("Poly1305"); + poly1305->set_key(auth_key); + poly1305->update(ctext, ptext_len); + poly1305->final(mac); + + return 0; + } + +int Sodium::crypto_secretbox_open_detached(uint8_t ptext[], + const uint8_t ctext[], + const uint8_t mac[], + size_t ctext_len, + const uint8_t nonce[], + const uint8_t key[]) + { + auto salsa = StreamCipher::create_or_throw("Salsa20"); + salsa->set_key(key, crypto_secretbox_KEYBYTES); + salsa->set_iv(nonce, crypto_secretbox_NONCEBYTES); + + secure_vector<uint8_t> auth_key(32); + salsa->write_keystream(auth_key.data(), auth_key.size()); + + auto poly1305 = MessageAuthenticationCode::create_or_throw("Poly1305"); + poly1305->set_key(auth_key); + poly1305->update(ctext, ctext_len); + secure_vector<uint8_t> computed_mac = poly1305->final(); + + if(!constant_time_compare(mac, computed_mac.data(), computed_mac.size())) + return -1; + + salsa->cipher(ctext, ptext, ctext_len); + + return 0; + } + +} diff --git a/src/lib/compat/sodium/sodium_utils.cpp b/src/lib/compat/sodium/sodium_utils.cpp new file mode 100644 index 000000000..afc4e8e01 --- /dev/null +++ b/src/lib/compat/sodium/sodium_utils.cpp @@ -0,0 +1,156 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/sodium.h> +#include <botan/chacha.h> +#include <botan/mem_ops.h> +#include <botan/system_rng.h> +#include <botan/internal/os_utils.h> +#include <botan/internal/ct_utils.h> +#include <botan/loadstor.h> + +namespace Botan { + +void Sodium::randombytes_buf(void* buf, size_t len) + { + system_rng().randomize(static_cast<uint8_t*>(buf), len); + } + +uint32_t Sodium::randombytes_uniform(uint32_t upper_bound) + { + if(upper_bound <= 1) + return 0; + + // Not completely uniform + uint64_t x; + randombytes_buf(&x, sizeof(x)); + return x % upper_bound; + } + +void Sodium::randombytes_buf_deterministic(void* buf, size_t size, const uint8_t seed[randombytes_SEEDBYTES]) + { + const unsigned char nonce[12] = { + 'L', 'i', 'b', 's', 'o', 'd', 'i', 'u', 'm', 'D', 'R', 'G' + }; + + ChaCha chacha(20); + chacha.set_key(seed, randombytes_SEEDBYTES); + chacha.set_iv(nonce, sizeof(nonce)); + chacha.write_keystream(static_cast<uint8_t*>(buf), size); + } + +int Sodium::crypto_verify_16(const uint8_t* x, const uint8_t* y) + { + return same_mem(x, y, 16); + } + +int Sodium::crypto_verify_32(const uint8_t* x, const uint8_t* y) + { + return same_mem(x, y, 32); + } + +int Sodium::crypto_verify_64(const uint8_t* x, const uint8_t* y) + { + return same_mem(x, y, 64); + } + +void Sodium::sodium_memzero(void* ptr, size_t len) + { + secure_scrub_memory(ptr, len); + } + +int Sodium::sodium_memcmp(const void* x, const void* y, size_t len) + { + const bool same = constant_time_compare(static_cast<const uint8_t*>(x), static_cast<const uint8_t*>(y), len); + return same ? 0 : -1; + } + +int Sodium::sodium_compare(const uint8_t x[], const uint8_t y[], size_t len) + { + const uint8_t LT = static_cast<uint8_t>(-1); + const uint8_t EQ = 0; + const uint8_t GT = 1; + + uint8_t result = EQ; // until found otherwise + + for(size_t i = 0; i != len; ++i) + { + const auto is_eq = CT::Mask<uint8_t>::is_equal(x[i], y[i]); + const auto is_lt = CT::Mask<uint8_t>::is_lt(x[i], y[i]); + result = is_eq.select(result, is_lt.select(LT, GT)); + } + + return static_cast<int8_t>(result); + } + +int Sodium::sodium_is_zero(const uint8_t b[], size_t len) + { + uint8_t sum = 0; + for(size_t i = 0; i != len; ++i) + sum |= b[i]; + return static_cast<int>(CT::Mask<uint8_t>::expand(sum).if_not_set_return(1)); + } + +void Sodium::sodium_increment(uint8_t b[], size_t len) + { + uint8_t carry = 1; + for(size_t i = 0; i != len; ++i) + { + b[i] += carry; + carry &= (b[i] == 0); + } + } + +void Sodium::sodium_add(uint8_t a[], const uint8_t b[], size_t len) + { + uint8_t carry = 0; + for(size_t i = 0; i != len; ++i) + { + a[i] += b[i] + carry; + carry = (a[i] < b[i]); + } + } + +void* Sodium::sodium_malloc(size_t size) + { + const uint64_t len = size; + uint8_t* p = static_cast<uint8_t*>(std::calloc(size + len, 1)); + store_le(len, p); + return p + 8; + } + +void Sodium::sodium_free(void* ptr) + { + if(ptr == nullptr) + return; + + uint8_t* p = static_cast<uint8_t*>(ptr) - 8; + const uint64_t len = load_le<uint64_t>(p, 0); + secure_scrub_memory(ptr, len); + std::free(p); + } + +void* Sodium::sodium_allocarray(size_t count, size_t size) + { + const size_t bytes = count * size; + if(bytes < count || bytes < size) + return nullptr; + return sodium_malloc(bytes); + } + +int Sodium::sodium_mprotect_noaccess(void* ptr) + { + OS::page_prohibit_access(ptr); + return 0; + } + +int Sodium::sodium_mprotect_readwrite(void* ptr) + { + OS::page_allow_access(ptr); + return 0; + } + +} diff --git a/src/lib/stream/salsa20/salsa20.cpp b/src/lib/stream/salsa20/salsa20.cpp index 407a3183e..1e30391d2 100644 --- a/src/lib/stream/salsa20/salsa20.cpp +++ b/src/lib/stream/salsa20/salsa20.cpp @@ -12,8 +12,6 @@ namespace Botan { -namespace { - #define SALSA20_QUARTER_ROUND(x1, x2, x3, x4) \ do { \ x2 ^= rotl<7>(x1 + x4); \ @@ -25,7 +23,8 @@ namespace { /* * Generate HSalsa20 cipher stream (for XSalsa20 IV setup) */ -void hsalsa20(uint32_t output[8], const uint32_t input[16]) +//static +void Salsa20::hsalsa20(uint32_t output[8], const uint32_t input[16]) { uint32_t x00 = input[ 0], x01 = input[ 1], x02 = input[ 2], x03 = input[ 3], x04 = input[ 4], x05 = input[ 5], x06 = input[ 6], x07 = input[ 7], @@ -55,8 +54,6 @@ void hsalsa20(uint32_t output[8], const uint32_t input[16]) output[7] = x09; } -} - /* * Generate Salsa20 cipher stream */ diff --git a/src/lib/stream/salsa20/salsa20.h b/src/lib/stream/salsa20/salsa20.h index 60143f8e0..0870c9fd2 100644 --- a/src/lib/stream/salsa20/salsa20.h +++ b/src/lib/stream/salsa20/salsa20.h @@ -33,6 +33,7 @@ class BOTAN_PUBLIC_API(2,0) Salsa20 final : public StreamCipher StreamCipher* clone() const override; static void salsa_core(uint8_t output[64], const uint32_t input[16], size_t rounds); + static void hsalsa20(uint32_t output[8], const uint32_t input[16]); void seek(uint64_t offset) override; private: |