mirror of https://github.com/oxen-io/session-ios
Updated to the latest version of the shared util library
# Conflicts: # Session/Onboarding/Onboarding.swiftpull/856/head
parent
1345e89809
commit
f5933bdf75
Binary file not shown.
Binary file not shown.
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int64_t seqno_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/// Wrapper around session::config::encrypt. message and key_base are binary: message has the
|
||||
/// length provided, key_base must be exactly 32 bytes. domain is a c string. Returns a newly
|
||||
/// allocated buffer containing the encrypted data, and sets the data's length into
|
||||
/// `ciphertext_size`. It is the caller's responsibility to `free()` the returned buffer!
|
||||
///
|
||||
/// Returns nullptr on error.
|
||||
unsigned char* config_encrypt(
|
||||
const unsigned char* message,
|
||||
size_t mlen,
|
||||
const unsigned char* key_base,
|
||||
const char* domain,
|
||||
size_t* ciphertext_size);
|
||||
|
||||
/// Works just like config_encrypt, but in reverse.
|
||||
unsigned char* config_decrypt(
|
||||
const unsigned char* ciphertext,
|
||||
size_t clen,
|
||||
const unsigned char* key_base,
|
||||
const char* domain,
|
||||
size_t* plaintext_size);
|
||||
|
||||
/// Returns the amount of padding needed for a plaintext of size s with encryption overhead
|
||||
/// `overhead`.
|
||||
size_t config_padded_size(size_t s, size_t overhead);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace session::config {
|
||||
|
||||
/// Encrypts a config message using XChaCha20-Poly1305, using a blake2b keyed hash of the message
|
||||
/// for the nonce (rather than pure random) so that different clients will encrypt the same data to
|
||||
/// the same encrypted value (thus allowing for server-side deduplication of identical messages).
|
||||
///
|
||||
/// `key_base` must be 32 bytes. This value is a fixed key that all clients that might receive this
|
||||
/// message can calculate independently (for instance a value derived from a secret key, or a shared
|
||||
/// random key). This key will be hashed with the message size and domain suffix (see below) to
|
||||
/// determine the actual encryption key.
|
||||
///
|
||||
/// `domain` is a short string (1-24 chars) used for the keyed hash. Typically this is the type of
|
||||
/// config, e.g. "closed-group" or "contacts". The full key will be
|
||||
/// "session-config-encrypted-message-[domain]". This value is also used for the encrypted key (see
|
||||
/// above).
|
||||
///
|
||||
/// The returned result will consist of encrypted data with authentication tag and appended nonce,
|
||||
/// suitable for being passed to decrypt() to authenticate and decrypt.
|
||||
///
|
||||
/// Throw std::invalid_argument on bad input (i.e. from invalid key_base or domain).
|
||||
ustring encrypt(ustring_view message, ustring_view key_base, std::string_view domain);
|
||||
|
||||
/// Same as above, but modifies `message` in place. `message` gets encrypted plus has the extra
|
||||
/// data and nonce appended.
|
||||
void encrypt_inplace(ustring& message, ustring_view key_base, std::string_view domain);
|
||||
|
||||
/// Constant amount of extra bytes required to be appended when encrypting.
|
||||
constexpr size_t ENCRYPT_DATA_OVERHEAD = 40; // ABYTES + NPUBBYTES
|
||||
|
||||
/// Thrown if decrypt() fails.
|
||||
struct decrypt_error : std::runtime_error {
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
/// Takes a value produced by `encrypt()` and decrypts it. `key_base` and `domain` must be the same
|
||||
/// given to encrypt or else decryption fails. Upon decryption failure a `decrypt_error` exception
|
||||
/// is thrown.
|
||||
ustring decrypt(ustring_view ciphertext, ustring_view key_base, std::string_view domain);
|
||||
|
||||
/// Same as above, but does in in-place. The string gets shortend to the plaintext after this call.
|
||||
void decrypt_inplace(ustring& ciphertext, ustring_view key_base, std::string_view domain);
|
||||
|
||||
/// Returns the target size of the message with padding, assuming an additional `overhead` bytes of
|
||||
/// overhead (e.g. from encrypt() overhead) will be appended. Will always return a value >= s +
|
||||
/// overhead.
|
||||
///
|
||||
/// Padding increments we use: 256 byte increments up to 5120; 1024 byte increments up to 20480,
|
||||
/// 2048 increments up to 40960, then 5120 from there up.
|
||||
inline constexpr size_t padded_size(size_t s, size_t overhead = ENCRYPT_DATA_OVERHEAD) {
|
||||
size_t s2 = s + overhead;
|
||||
size_t chunk = s2 < 5120 ? 256 : s2 < 20480 ? 1024 : s2 < 40960 ? 2048 : 5120;
|
||||
return (s2 + chunk - 1) / chunk * chunk - overhead;
|
||||
}
|
||||
|
||||
/// Inserts null byte padding to the beginning of a message to make the final message size granular.
|
||||
/// See the above function for the sizes.
|
||||
///
|
||||
/// \param data - the data; this is modified in place.
|
||||
/// \param overhead - encryption overhead to account for to reach the desired padded size. The
|
||||
/// default, if omitted, is the space used by the `encrypt()` function defined above.
|
||||
void pad_message(ustring& data, size_t overhead = ENCRYPT_DATA_OVERHEAD);
|
||||
|
||||
} // namespace session::config
|
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
#define LIBSESSION_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define LIBSESSION_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
#define LIBSESSION_C_API extern "C" LIBSESSION_EXPORT
|
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace session {
|
||||
|
||||
using ustring = std::basic_string<unsigned char>;
|
||||
using ustring_view = std::basic_string_view<unsigned char>;
|
||||
|
||||
namespace config {
|
||||
|
||||
using seqno_t = std::int64_t;
|
||||
|
||||
} // namespace config
|
||||
|
||||
} // namespace session
|
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "types.hpp"
|
||||
|
||||
namespace session {
|
||||
|
||||
// Helper function to go to/from char pointers to unsigned char pointers:
|
||||
inline const unsigned char* to_unsigned(const char* x) {
|
||||
return reinterpret_cast<const unsigned char*>(x);
|
||||
}
|
||||
inline unsigned char* to_unsigned(char* x) {
|
||||
return reinterpret_cast<unsigned char*>(x);
|
||||
}
|
||||
inline const char* from_unsigned(const unsigned char* x) {
|
||||
return reinterpret_cast<const char*>(x);
|
||||
}
|
||||
inline char* from_unsigned(unsigned char* x) {
|
||||
return reinterpret_cast<char*>(x);
|
||||
}
|
||||
// Helper function to switch between string_view and ustring_view
|
||||
inline ustring_view to_unsigned_sv(std::string_view v) {
|
||||
return {to_unsigned(v.data()), v.size()};
|
||||
}
|
||||
inline std::string_view from_unsigned_sv(ustring_view v) {
|
||||
return {from_unsigned(v.data()), v.size()};
|
||||
}
|
||||
|
||||
} // namespace session
|
Loading…
Reference in New Issue