Merge commit '2e7800c' into logging_enabled
This commit is contained in:
commit
cd942f32c1
34 changed files with 1150 additions and 811 deletions
2
Makefile
2
Makefile
|
@ -12,7 +12,7 @@ JS_TARGET := javascript/olm.js
|
||||||
|
|
||||||
JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json
|
JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json
|
||||||
|
|
||||||
PUBLIC_HEADERS := include/olm/olm.hh
|
PUBLIC_HEADERS := include/olm/olm.h
|
||||||
|
|
||||||
SOURCES := $(wildcard src/*.cpp) $(wildcard src/*.c)
|
SOURCES := $(wildcard src/*.cpp) $(wildcard src/*.c)
|
||||||
RELEASE_OBJECTS := $(patsubst src/%,$(BUILD_DIR)/release/%,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES))))
|
RELEASE_OBJECTS := $(patsubst src/%,$(BUILD_DIR)/release/%,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES))))
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include "olm/list.hh"
|
#include "olm/list.hh"
|
||||||
#include "olm/crypto.hh"
|
#include "olm/crypto.hh"
|
||||||
#include "olm/error.hh"
|
#include "olm/error.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ struct Account {
|
||||||
IdentityKeys identity_keys;
|
IdentityKeys identity_keys;
|
||||||
List<OneTimeKey, MAX_ONE_TIME_KEYS> one_time_keys;
|
List<OneTimeKey, MAX_ONE_TIME_KEYS> one_time_keys;
|
||||||
std::uint32_t next_one_time_key_id;
|
std::uint32_t next_one_time_key_id;
|
||||||
ErrorCode last_error;
|
OlmErrorCode last_error;
|
||||||
|
|
||||||
/** Number of random bytes needed to create a new account */
|
/** Number of random bytes needed to create a new account */
|
||||||
std::size_t new_account_random_length();
|
std::size_t new_account_random_length();
|
||||||
|
|
77
include/olm/base64.h
Normal file
77
include/olm/base64.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/* Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* C bindings for base64 functions */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OLM_BASE64_H_
|
||||||
|
#define OLM_BASE64_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of bytes of unpadded base64 needed to encode a length of input.
|
||||||
|
*/
|
||||||
|
size_t _olm_encode_base64_length(
|
||||||
|
size_t input_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the raw input as unpadded base64.
|
||||||
|
* Writes encode_base64_length(input_length) bytes to the output buffer.
|
||||||
|
* The input can overlap with the last three quarters of the output buffer.
|
||||||
|
* That is, the input pointer may be output + output_length - input_length.
|
||||||
|
*
|
||||||
|
* Returns number of bytes encoded
|
||||||
|
*/
|
||||||
|
size_t _olm_encode_base64(
|
||||||
|
uint8_t const * input, size_t input_length,
|
||||||
|
uint8_t * output
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of bytes of raw data a length of unpadded base64 will encode to.
|
||||||
|
* Returns size_t(-1) if the length is not a valid length for base64.
|
||||||
|
*/
|
||||||
|
size_t _olm_decode_base64_length(
|
||||||
|
size_t input_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the unpadded base64 input to raw bytes.
|
||||||
|
* Writes decode_base64_length(input_length) bytes to the output buffer.
|
||||||
|
* The output can overlap with the first three quarters of the input buffer.
|
||||||
|
* That is, the input pointers and output pointer may be the same.
|
||||||
|
*
|
||||||
|
* Returns number of bytes decoded
|
||||||
|
*/
|
||||||
|
size_t _olm_decode_base64(
|
||||||
|
uint8_t const * input, size_t input_length,
|
||||||
|
uint8_t * output
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* OLM_BASE64_H_ */
|
138
include/olm/cipher.h
Normal file
138
include/olm/cipher.h
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
/* Copyright 2015 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OLM_CIPHER_H_
|
||||||
|
#define OLM_CIPHER_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct _olm_cipher;
|
||||||
|
|
||||||
|
struct _olm_cipher_ops {
|
||||||
|
/**
|
||||||
|
* Returns the length of the message authentication code that will be
|
||||||
|
* appended to the output.
|
||||||
|
*/
|
||||||
|
size_t (*mac_length)(const struct _olm_cipher *cipher);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the length of cipher-text for a given length of plain-text.
|
||||||
|
*/
|
||||||
|
size_t (*encrypt_ciphertext_length)(
|
||||||
|
const struct _olm_cipher *cipher,
|
||||||
|
size_t plaintext_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encrypts the plain-text into the output buffer and authenticates the
|
||||||
|
* contents of the output buffer covering both cipher-text and any other
|
||||||
|
* associated data in the output buffer.
|
||||||
|
*
|
||||||
|
* |---------------------------------------output_length-->|
|
||||||
|
* output |--ciphertext_length-->| |---mac_length-->|
|
||||||
|
* ciphertext
|
||||||
|
*
|
||||||
|
* The plain-text pointers and cipher-text pointers may be the same.
|
||||||
|
*
|
||||||
|
* Returns size_t(-1) if the length of the cipher-text or the output
|
||||||
|
* buffer is too small. Otherwise returns the length of the output buffer.
|
||||||
|
*/
|
||||||
|
size_t (*encrypt)(
|
||||||
|
const struct _olm_cipher *cipher,
|
||||||
|
uint8_t const * key, size_t key_length,
|
||||||
|
uint8_t const * plaintext, size_t plaintext_length,
|
||||||
|
uint8_t * ciphertext, size_t ciphertext_length,
|
||||||
|
uint8_t * output, size_t output_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum length of plain-text that a given length of
|
||||||
|
* cipher-text can contain.
|
||||||
|
*/
|
||||||
|
size_t (*decrypt_max_plaintext_length)(
|
||||||
|
const struct _olm_cipher *cipher,
|
||||||
|
size_t ciphertext_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticates the input and decrypts the cipher-text into the plain-text
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* |----------------------------------------input_length-->|
|
||||||
|
* input |--ciphertext_length-->| |---mac_length-->|
|
||||||
|
* ciphertext
|
||||||
|
*
|
||||||
|
* The plain-text pointers and cipher-text pointers may be the same.
|
||||||
|
*
|
||||||
|
* Returns size_t(-1) if the length of the plain-text buffer is too
|
||||||
|
* small or if the authentication check fails. Otherwise returns the length
|
||||||
|
* of the plain text.
|
||||||
|
*/
|
||||||
|
size_t (*decrypt)(
|
||||||
|
const struct _olm_cipher *cipher,
|
||||||
|
uint8_t const * key, size_t key_length,
|
||||||
|
uint8_t const * input, size_t input_length,
|
||||||
|
uint8_t const * ciphertext, size_t ciphertext_length,
|
||||||
|
uint8_t * plaintext, size_t max_plaintext_length
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _olm_cipher {
|
||||||
|
const struct _olm_cipher_ops *ops;
|
||||||
|
/* cipher-specific fields follow */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _olm_cipher_aes_sha_256 {
|
||||||
|
struct _olm_cipher base_cipher;
|
||||||
|
|
||||||
|
/** context string for the HKDF used for deriving the AES256 key, HMAC key,
|
||||||
|
* and AES IV, from the key material passed to encrypt/decrypt.
|
||||||
|
*/
|
||||||
|
uint8_t const * kdf_info;
|
||||||
|
|
||||||
|
/** length of context string kdf_info */
|
||||||
|
size_t kdf_info_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct _olm_cipher_ops _olm_cipher_aes_sha_256_ops;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get an initializer for an instance of struct _olm_cipher_aes_sha_256.
|
||||||
|
*
|
||||||
|
* To use it, declare:
|
||||||
|
*
|
||||||
|
* struct _olm_cipher_aes_sha_256 MY_CIPHER =
|
||||||
|
* OLM_CIPHER_INIT_AES_SHA_256("MY_KDF");
|
||||||
|
* struct _olm_cipher *cipher = OLM_CIPHER_BASE(&MY_CIPHER);
|
||||||
|
*/
|
||||||
|
#define OLM_CIPHER_INIT_AES_SHA_256(KDF_INFO) { \
|
||||||
|
.base_cipher = { &_olm_cipher_aes_sha_256_ops },\
|
||||||
|
.kdf_info = (uint8_t *)(KDF_INFO), \
|
||||||
|
.kdf_info_length = sizeof(KDF_INFO) - 1 \
|
||||||
|
}
|
||||||
|
#define OLM_CIPHER_BASE(CIPHER) \
|
||||||
|
(&((CIPHER)->base_cipher))
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OLM_CIPHER_H_ */
|
|
@ -1,132 +0,0 @@
|
||||||
/* Copyright 2015 OpenMarket Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef OLM_CIPHER_HH_
|
|
||||||
#define OLM_CIPHER_HH_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
namespace olm {
|
|
||||||
|
|
||||||
class Cipher {
|
|
||||||
public:
|
|
||||||
virtual ~Cipher();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the length of the message authentication code that will be
|
|
||||||
* appended to the output.
|
|
||||||
*/
|
|
||||||
virtual std::size_t mac_length() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the length of cipher-text for a given length of plain-text.
|
|
||||||
*/
|
|
||||||
virtual std::size_t encrypt_ciphertext_length(
|
|
||||||
std::size_t plaintext_length
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Encrypts the plain-text into the output buffer and authenticates the
|
|
||||||
* contents of the output buffer covering both cipher-text and any other
|
|
||||||
* associated data in the output buffer.
|
|
||||||
*
|
|
||||||
* |---------------------------------------output_length-->|
|
|
||||||
* output |--ciphertext_length-->| |---mac_length-->|
|
|
||||||
* ciphertext
|
|
||||||
*
|
|
||||||
* The plain-text pointers and cipher-text pointers may be the same.
|
|
||||||
*
|
|
||||||
* Returns std::size_t(-1) if the length of the cipher-text or the output
|
|
||||||
* buffer is too small. Otherwise returns the length of the output buffer.
|
|
||||||
*/
|
|
||||||
virtual std::size_t encrypt(
|
|
||||||
std::uint8_t const * key, std::size_t key_length,
|
|
||||||
std::uint8_t const * plaintext, std::size_t plaintext_length,
|
|
||||||
std::uint8_t * ciphertext, std::size_t ciphertext_length,
|
|
||||||
std::uint8_t * output, std::size_t output_length
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the maximum length of plain-text that a given length of
|
|
||||||
* cipher-text can contain.
|
|
||||||
*/
|
|
||||||
virtual std::size_t decrypt_max_plaintext_length(
|
|
||||||
std::size_t ciphertext_length
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Authenticates the input and decrypts the cipher-text into the plain-text
|
|
||||||
* buffer.
|
|
||||||
*
|
|
||||||
* |----------------------------------------input_length-->|
|
|
||||||
* input |--ciphertext_length-->| |---mac_length-->|
|
|
||||||
* ciphertext
|
|
||||||
*
|
|
||||||
* The plain-text pointers and cipher-text pointers may be the same.
|
|
||||||
*
|
|
||||||
* Returns std::size_t(-1) if the length of the plain-text buffer is too
|
|
||||||
* small or if the authentication check fails. Otherwise returns the length
|
|
||||||
* of the plain text.
|
|
||||||
*/
|
|
||||||
virtual std::size_t decrypt(
|
|
||||||
std::uint8_t const * key, std::size_t key_length,
|
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
|
||||||
std::uint8_t const * ciphertext, std::size_t ciphertext_length,
|
|
||||||
std::uint8_t * plaintext, std::size_t max_plaintext_length
|
|
||||||
) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class CipherAesSha256 : public Cipher {
|
|
||||||
public:
|
|
||||||
CipherAesSha256(
|
|
||||||
std::uint8_t const * kdf_info, std::size_t kdf_info_length
|
|
||||||
);
|
|
||||||
|
|
||||||
virtual std::size_t mac_length() const;
|
|
||||||
|
|
||||||
virtual std::size_t encrypt_ciphertext_length(
|
|
||||||
std::size_t plaintext_length
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual std::size_t encrypt(
|
|
||||||
std::uint8_t const * key, std::size_t key_length,
|
|
||||||
std::uint8_t const * plaintext, std::size_t plaintext_length,
|
|
||||||
std::uint8_t * ciphertext, std::size_t ciphertext_length,
|
|
||||||
std::uint8_t * output, std::size_t output_length
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual std::size_t decrypt_max_plaintext_length(
|
|
||||||
std::size_t ciphertext_length
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual std::size_t decrypt(
|
|
||||||
std::uint8_t const * key, std::size_t key_length,
|
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
|
||||||
std::uint8_t const * ciphertext, std::size_t ciphertext_length,
|
|
||||||
std::uint8_t * plaintext, std::size_t max_plaintext_length
|
|
||||||
) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::uint8_t const * kdf_info;
|
|
||||||
std::size_t kdf_info_length;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* OLM_CIPHER_HH_ */
|
|
65
include/olm/crypto.h
Normal file
65
include/olm/crypto.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/* Copyright 2015 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* C-compatible crpyto utility functions. At some point all of crypto.hh will
|
||||||
|
* move here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OLM_CRYPTO_H_
|
||||||
|
#define OLM_CRYPTO_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const size_t SHA256_OUTPUT_LENGTH = 32;
|
||||||
|
|
||||||
|
/** Computes SHA-256 of the input. The output buffer must be a least 32
|
||||||
|
* bytes long. */
|
||||||
|
void _olm_crypto_sha256(
|
||||||
|
uint8_t const * input, size_t input_length,
|
||||||
|
uint8_t * output
|
||||||
|
);
|
||||||
|
|
||||||
|
/** HMAC: Keyed-Hashing for Message Authentication
|
||||||
|
* http://tools.ietf.org/html/rfc2104
|
||||||
|
* Computes HMAC-SHA-256 of the input for the key. The output buffer must
|
||||||
|
* be at least 32 bytes long. */
|
||||||
|
void _olm_crypto_hmac_sha256(
|
||||||
|
uint8_t const * key, size_t key_length,
|
||||||
|
uint8_t const * input, size_t input_length,
|
||||||
|
uint8_t * output
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/** HMAC-based Key Derivation Function (HKDF)
|
||||||
|
* https://tools.ietf.org/html/rfc5869
|
||||||
|
* Derives key material from the input bytes. */
|
||||||
|
void _olm_crypto_hkdf_sha256(
|
||||||
|
uint8_t const * input, size_t input_length,
|
||||||
|
uint8_t const * info, size_t info_length,
|
||||||
|
uint8_t const * salt, size_t salt_length,
|
||||||
|
uint8_t * output, size_t output_length
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OLM_CRYPTO_H_ */
|
|
@ -19,6 +19,11 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
// eventually all of this needs to move into crypto.h, and everything should
|
||||||
|
// use that. For now, include crypto.h here.
|
||||||
|
|
||||||
|
#include "olm/crypto.h"
|
||||||
|
|
||||||
namespace olm {
|
namespace olm {
|
||||||
|
|
||||||
static const std::size_t KEY_LENGTH = 32;
|
static const std::size_t KEY_LENGTH = 32;
|
||||||
|
@ -144,38 +149,6 @@ std::size_t aes_decrypt_cbc(
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/** Computes SHA-256 of the input. The output buffer must be a least 32
|
|
||||||
* bytes long. */
|
|
||||||
void sha256(
|
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
|
||||||
std::uint8_t * output
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
const std::size_t SHA256_OUTPUT_LENGTH = 32;
|
|
||||||
|
|
||||||
|
|
||||||
/** HMAC: Keyed-Hashing for Message Authentication
|
|
||||||
* http://tools.ietf.org/html/rfc2104
|
|
||||||
* Computes HMAC-SHA-256 of the input for the key. The output buffer must
|
|
||||||
* be at least 32 bytes long. */
|
|
||||||
void hmac_sha256(
|
|
||||||
std::uint8_t const * key, std::size_t key_length,
|
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
|
||||||
std::uint8_t * output
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/** HMAC-based Key Derivation Function (HKDF)
|
|
||||||
* https://tools.ietf.org/html/rfc5869
|
|
||||||
* Derives key material from the input bytes. */
|
|
||||||
void hkdf_sha256(
|
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
|
||||||
std::uint8_t const * info, std::size_t info_length,
|
|
||||||
std::uint8_t const * salt, std::size_t salt_length,
|
|
||||||
std::uint8_t * output, std::size_t output_length
|
|
||||||
);
|
|
||||||
|
|
||||||
} // namespace olm
|
} // namespace olm
|
||||||
|
|
||||||
#endif /* OLM_CRYPTO_HH_ */
|
#endif /* OLM_CRYPTO_HH_ */
|
||||||
|
|
40
include/olm/error.h
Normal file
40
include/olm/error.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/* Copyright 2015-2016 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef OLM_ERROR_H_
|
||||||
|
#define OLM_ERROR_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum OlmErrorCode {
|
||||||
|
OLM_SUCCESS = 0, /*!< There wasn't an error */
|
||||||
|
OLM_NOT_ENOUGH_RANDOM = 1, /*!< Not enough entropy was supplied */
|
||||||
|
OLM_OUTPUT_BUFFER_TOO_SMALL = 2, /*!< Supplied output buffer is too small */
|
||||||
|
OLM_BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */
|
||||||
|
OLM_BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */
|
||||||
|
OLM_BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */
|
||||||
|
OLM_BAD_MESSAGE_KEY_ID = 6, /*!< The message references an unknown key id */
|
||||||
|
OLM_INVALID_BASE64 = 7, /*!< The input base64 was invalid */
|
||||||
|
OLM_BAD_ACCOUNT_KEY = 8, /*!< The supplied account key is invalid */
|
||||||
|
OLM_UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */
|
||||||
|
OLM_CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OLM_ERROR_H_ */
|
|
@ -1,36 +0,0 @@
|
||||||
/* Copyright 2015 OpenMarket Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
#ifndef ERROR_HH_
|
|
||||||
#define ERROR_HH_
|
|
||||||
|
|
||||||
namespace olm {
|
|
||||||
|
|
||||||
enum struct ErrorCode {
|
|
||||||
SUCCESS = 0, /*!< There wasn't an error */
|
|
||||||
NOT_ENOUGH_RANDOM = 1, /*!< Not enough entropy was supplied */
|
|
||||||
OUTPUT_BUFFER_TOO_SMALL = 2, /*!< Supplied output buffer is too small */
|
|
||||||
BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */
|
|
||||||
BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */
|
|
||||||
BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */
|
|
||||||
BAD_MESSAGE_KEY_ID = 6, /*!< The message references an unknown key id */
|
|
||||||
INVALID_BASE64 = 7, /*!< The input base64 was invalid */
|
|
||||||
BAD_ACCOUNT_KEY = 8, /*!< The supplied account key is invalid */
|
|
||||||
UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */
|
|
||||||
CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace olm
|
|
||||||
|
|
||||||
#endif /* ERROR_HH_ */
|
|
41
include/olm/memory.h
Normal file
41
include/olm/memory.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/* Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* C bindings for memory functions */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OLM_MEMORY_H_
|
||||||
|
#define OLM_MEMORY_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the memory held in the buffer. This is more resilient to being
|
||||||
|
* optimised away than memset or bzero.
|
||||||
|
*/
|
||||||
|
void _olm_unset(
|
||||||
|
void volatile * buffer, size_t buffer_length
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* OLM_MEMORY_H_ */
|
430
include/olm/olm.h
Normal file
430
include/olm/olm.h
Normal file
|
@ -0,0 +1,430 @@
|
||||||
|
/* Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OLM_H_
|
||||||
|
#define OLM_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const size_t OLM_MESSAGE_TYPE_PRE_KEY = 0;
|
||||||
|
static const size_t OLM_MESSAGE_TYPE_MESSAGE = 1;
|
||||||
|
|
||||||
|
typedef struct OlmAccount OlmAccount;
|
||||||
|
typedef struct OlmSession OlmSession;
|
||||||
|
typedef struct OlmUtility OlmUtility;
|
||||||
|
|
||||||
|
/** The size of an account object in bytes */
|
||||||
|
size_t olm_account_size();
|
||||||
|
|
||||||
|
/** The size of a session object in bytes */
|
||||||
|
size_t olm_session_size();
|
||||||
|
|
||||||
|
/** The size of a utility object in bytes */
|
||||||
|
size_t olm_utility_size();
|
||||||
|
|
||||||
|
/** Initialise an account object using the supplied memory
|
||||||
|
* The supplied memory must be at least olm_account_size() bytes */
|
||||||
|
OlmAccount * olm_account(
|
||||||
|
void * memory
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Initialise a session object using the supplied memory
|
||||||
|
* The supplied memory must be at least olm_session_size() bytes */
|
||||||
|
OlmSession * olm_session(
|
||||||
|
void * memory
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Initialise a utility object using the supplied memory
|
||||||
|
* The supplied memory must be at least olm_utility_size() bytes */
|
||||||
|
OlmUtility * olm_utility(
|
||||||
|
void * memory
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The value that olm will return from a function if there was an error */
|
||||||
|
size_t olm_error();
|
||||||
|
|
||||||
|
/** A null terminated string describing the most recent error to happen to an
|
||||||
|
* account */
|
||||||
|
const char * olm_account_last_error(
|
||||||
|
OlmAccount * account
|
||||||
|
);
|
||||||
|
|
||||||
|
/** A null terminated string describing the most recent error to happen to a
|
||||||
|
* session */
|
||||||
|
const char * olm_session_last_error(
|
||||||
|
OlmSession * session
|
||||||
|
);
|
||||||
|
|
||||||
|
/** A null terminated string describing the most recent error to happen to a
|
||||||
|
* utility */
|
||||||
|
const char * olm_utility_last_error(
|
||||||
|
OlmUtility * utility
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Clears the memory used to back this account */
|
||||||
|
size_t olm_clear_account(
|
||||||
|
OlmAccount * account
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Clears the memory used to back this session */
|
||||||
|
size_t olm_clear_session(
|
||||||
|
OlmSession * session
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Clears the memory used to back this utility */
|
||||||
|
size_t olm_clear_utility(
|
||||||
|
OlmUtility * utility
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Returns the number of bytes needed to store an account */
|
||||||
|
size_t olm_pickle_account_length(
|
||||||
|
OlmAccount * account
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Returns the number of bytes needed to store a session */
|
||||||
|
size_t olm_pickle_session_length(
|
||||||
|
OlmSession * session
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Stores an account as a base64 string. Encrypts the account using the
|
||||||
|
* supplied key. Returns the length of the pickled account on success.
|
||||||
|
* Returns olm_error() on failure. If the pickle output buffer
|
||||||
|
* is smaller than olm_pickle_account_length() then
|
||||||
|
* olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
|
||||||
|
size_t olm_pickle_account(
|
||||||
|
OlmAccount * account,
|
||||||
|
void const * key, size_t key_length,
|
||||||
|
void * pickled, size_t pickled_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Stores a session as a base64 string. Encrypts the session using the
|
||||||
|
* supplied key. Returns the length of the pickled session on success.
|
||||||
|
* Returns olm_error() on failure. If the pickle output buffer
|
||||||
|
* is smaller than olm_pickle_session_length() then
|
||||||
|
* olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
|
||||||
|
size_t olm_pickle_session(
|
||||||
|
OlmSession * session,
|
||||||
|
void const * key, size_t key_length,
|
||||||
|
void * pickled, size_t pickled_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Loads an account from a pickled base64 string. Decrypts the account using
|
||||||
|
* the supplied key. Returns olm_error() on failure. If the key doesn't
|
||||||
|
* match the one used to encrypt the account then olm_account_last_error()
|
||||||
|
* will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
|
||||||
|
* olm_account_last_error() will be "INVALID_BASE64". The input pickled
|
||||||
|
* buffer is destroyed */
|
||||||
|
size_t olm_unpickle_account(
|
||||||
|
OlmAccount * account,
|
||||||
|
void const * key, size_t key_length,
|
||||||
|
void * pickled, size_t pickled_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Loads a session from a pickled base64 string. Decrypts the session using
|
||||||
|
* the supplied key. Returns olm_error() on failure. If the key doesn't
|
||||||
|
* match the one used to encrypt the account then olm_session_last_error()
|
||||||
|
* will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
|
||||||
|
* olm_session_last_error() will be "INVALID_BASE64". The input pickled
|
||||||
|
* buffer is destroyed */
|
||||||
|
size_t olm_unpickle_session(
|
||||||
|
OlmSession * session,
|
||||||
|
void const * key, size_t key_length,
|
||||||
|
void * pickled, size_t pickled_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The number of random bytes needed to create an account.*/
|
||||||
|
size_t olm_create_account_random_length(
|
||||||
|
OlmAccount * account
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Creates a new account. Returns olm_error() on failure. If weren't
|
||||||
|
* enough random bytes then olm_account_last_error() will be
|
||||||
|
* "NOT_ENOUGH_RANDOM" */
|
||||||
|
size_t olm_create_account(
|
||||||
|
OlmAccount * account,
|
||||||
|
void * random, size_t random_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The size of the output buffer needed to hold the identity keys */
|
||||||
|
size_t olm_account_identity_keys_length(
|
||||||
|
OlmAccount * account
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Writes the public parts of the identity keys for the account into the
|
||||||
|
* identity_keys output buffer. Returns olm_error() on failure. If the
|
||||||
|
* identity_keys buffer was too small then olm_account_last_error() will be
|
||||||
|
* "OUTPUT_BUFFER_TOO_SMALL". */
|
||||||
|
size_t olm_account_identity_keys(
|
||||||
|
OlmAccount * account,
|
||||||
|
void * identity_keys, size_t identity_key_length
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/** The length of an ed25519 signature encoded as base64. */
|
||||||
|
size_t olm_account_signature_length(
|
||||||
|
OlmAccount * account
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Signs a message with the ed25519 key for this account. Returns olm_error()
|
||||||
|
* on failure. If the signature buffer was too small then
|
||||||
|
* olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
|
||||||
|
size_t olm_account_sign(
|
||||||
|
OlmAccount * account,
|
||||||
|
void const * message, size_t message_length,
|
||||||
|
void * signature, size_t signature_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The size of the output buffer needed to hold the one time keys */
|
||||||
|
size_t olm_account_one_time_keys_length(
|
||||||
|
OlmAccount * account
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Writes the public parts of the unpublished one time keys for the account
|
||||||
|
* into the one_time_keys output buffer. Returns olm_error() on failure.
|
||||||
|
* If the one_time_keys buffer was too small then olm_account_last_error()
|
||||||
|
* will be "OUTPUT_BUFFER_TOO_SMALL". */
|
||||||
|
size_t olm_account_one_time_keys(
|
||||||
|
OlmAccount * account,
|
||||||
|
void * one_time_keys, size_t one_time_keys_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Marks the current set of one time keys as being published. */
|
||||||
|
size_t olm_account_mark_keys_as_published(
|
||||||
|
OlmAccount * account
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The largest number of one time keys this account can store. */
|
||||||
|
size_t olm_account_max_number_of_one_time_keys(
|
||||||
|
OlmAccount * account
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The number of random bytes needed to generate a given number of new one
|
||||||
|
* time keys. */
|
||||||
|
size_t olm_account_generate_one_time_keys_random_length(
|
||||||
|
OlmAccount * account,
|
||||||
|
size_t number_of_keys
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Generates a number of new one time keys. If the total number of keys stored
|
||||||
|
* by this account exceeds max_number_of_one_time_keys() then the old keys are
|
||||||
|
* discarded. Returns olm_error() on error. If the number of random bytes is
|
||||||
|
* too small then olm_account_last_error() will be "NOT_ENOUGH_RANDOM". */
|
||||||
|
size_t olm_account_generate_one_time_keys(
|
||||||
|
OlmAccount * account,
|
||||||
|
size_t number_of_keys,
|
||||||
|
void * random, size_t random_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The number of random bytes needed to create an outbound session */
|
||||||
|
size_t olm_create_outbound_session_random_length(
|
||||||
|
OlmSession * session
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Creates a new out-bound session for sending messages to a given identity_key
|
||||||
|
* and one_time_key. Returns olm_error() on failure. If the keys couldn't be
|
||||||
|
* decoded as base64 then olm_session_last_error() will be "INVALID_BASE64"
|
||||||
|
* If there weren't enough random bytes then olm_session_last_error() will
|
||||||
|
* be "NOT_ENOUGH_RANDOM". */
|
||||||
|
size_t olm_create_outbound_session(
|
||||||
|
OlmSession * session,
|
||||||
|
OlmAccount * account,
|
||||||
|
void const * their_identity_key, size_t their_identity_key_length,
|
||||||
|
void const * their_one_time_key, size_t their_one_time_key_length,
|
||||||
|
void * random, size_t random_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Create a new in-bound session for sending/receiving messages from an
|
||||||
|
* incoming PRE_KEY message. Returns olm_error() on failure. If the base64
|
||||||
|
* couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
|
||||||
|
* If the message was for an unsupported protocol version then
|
||||||
|
* olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
|
||||||
|
* couldn't be decoded then then olm_session_last_error() will be
|
||||||
|
* "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time
|
||||||
|
* key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */
|
||||||
|
size_t olm_create_inbound_session(
|
||||||
|
OlmSession * session,
|
||||||
|
OlmAccount * account,
|
||||||
|
void * one_time_key_message, size_t message_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Create a new in-bound session for sending/receiving messages from an
|
||||||
|
* incoming PRE_KEY message. Returns olm_error() on failure. If the base64
|
||||||
|
* couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
|
||||||
|
* If the message was for an unsupported protocol version then
|
||||||
|
* olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
|
||||||
|
* couldn't be decoded then then olm_session_last_error() will be
|
||||||
|
* "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time
|
||||||
|
* key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */
|
||||||
|
size_t olm_create_inbound_session_from(
|
||||||
|
OlmSession * session,
|
||||||
|
OlmAccount * account,
|
||||||
|
void const * their_identity_key, size_t their_identity_key_length,
|
||||||
|
void * one_time_key_message, size_t message_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The length of the buffer needed to return the id for this session. */
|
||||||
|
size_t olm_session_id_length(
|
||||||
|
OlmSession * session
|
||||||
|
);
|
||||||
|
|
||||||
|
/** An identifier for this session. Will be the same for both ends of the
|
||||||
|
* conversation. If the id buffer is too small then olm_session_last_error()
|
||||||
|
* will be "OUTPUT_BUFFER_TOO_SMALL". */
|
||||||
|
size_t olm_session_id(
|
||||||
|
OlmSession * session,
|
||||||
|
void * id, size_t id_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Checks if the PRE_KEY message is for this in-bound session. This can happen
|
||||||
|
* if multiple messages are sent to this account before this account sends a
|
||||||
|
* message in reply. Returns olm_error() on failure. If the base64
|
||||||
|
* couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
|
||||||
|
* If the message was for an unsupported protocol version then
|
||||||
|
* olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
|
||||||
|
* couldn't be decoded then then olm_session_last_error() will be
|
||||||
|
* "BAD_MESSAGE_FORMAT". */
|
||||||
|
size_t olm_matches_inbound_session(
|
||||||
|
OlmSession * session,
|
||||||
|
void * one_time_key_message, size_t message_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Checks if the PRE_KEY message is for this in-bound session. This can happen
|
||||||
|
* if multiple messages are sent to this account before this account sends a
|
||||||
|
* message in reply. Returns olm_error() on failure. If the base64
|
||||||
|
* couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
|
||||||
|
* If the message was for an unsupported protocol version then
|
||||||
|
* olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
|
||||||
|
* couldn't be decoded then then olm_session_last_error() will be
|
||||||
|
* "BAD_MESSAGE_FORMAT". */
|
||||||
|
size_t olm_matches_inbound_session_from(
|
||||||
|
OlmSession * session,
|
||||||
|
void const * their_identity_key, size_t their_identity_key_length,
|
||||||
|
void * one_time_key_message, size_t message_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Removes the one time keys that the session used from the account. Returns
|
||||||
|
* olm_error() on failure. If the account doesn't have any matching one time
|
||||||
|
* keys then olm_account_last_error() will be "BAD_MESSAGE_KEY_ID". */
|
||||||
|
size_t olm_remove_one_time_keys(
|
||||||
|
OlmAccount * account,
|
||||||
|
OlmSession * session
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The type of the next message that olm_encrypt() will return. Returns
|
||||||
|
* OLM_MESSAGE_TYPE_PRE_KEY if the message will be a PRE_KEY message.
|
||||||
|
* Returns OLM_MESSAGE_TYPE_MESSAGE if the message will be a normal message.
|
||||||
|
* Returns olm_error on failure. */
|
||||||
|
size_t olm_encrypt_message_type(
|
||||||
|
OlmSession * session
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The number of random bytes needed to encrypt the next message. */
|
||||||
|
size_t olm_encrypt_random_length(
|
||||||
|
OlmSession * session
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The size of the next message in bytes for the given number of plain-text
|
||||||
|
* bytes. */
|
||||||
|
size_t olm_encrypt_message_length(
|
||||||
|
OlmSession * session,
|
||||||
|
size_t plaintext_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Encrypts a message using the session. Returns the length of the message in
|
||||||
|
* bytes on success. Writes the message as base64 into the message buffer.
|
||||||
|
* Returns olm_error() on failure. If the message buffer is too small then
|
||||||
|
* olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If there
|
||||||
|
* weren't enough random bytes then olm_session_last_error() will be
|
||||||
|
* "NOT_ENOUGH_RANDOM". */
|
||||||
|
size_t olm_encrypt(
|
||||||
|
OlmSession * session,
|
||||||
|
void const * plaintext, size_t plaintext_length,
|
||||||
|
void * random, size_t random_length,
|
||||||
|
void * message, size_t message_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The maximum number of bytes of plain-text a given message could decode to.
|
||||||
|
* The actual size could be different due to padding. The input message buffer
|
||||||
|
* is destroyed. Returns olm_error() on failure. If the message base64
|
||||||
|
* couldn't be decoded then olm_session_last_error() will be
|
||||||
|
* "INVALID_BASE64". If the message is for an unsupported version of the
|
||||||
|
* protocol then olm_session_last_error() will be "BAD_MESSAGE_VERSION".
|
||||||
|
* If the message couldn't be decoded then olm_session_last_error() will be
|
||||||
|
* "BAD_MESSAGE_FORMAT". */
|
||||||
|
size_t olm_decrypt_max_plaintext_length(
|
||||||
|
OlmSession * session,
|
||||||
|
size_t message_type,
|
||||||
|
void * message, size_t message_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Decrypts a message using the session. The input message buffer is destroyed.
|
||||||
|
* Returns the length of the plain-text on success. Returns olm_error() on
|
||||||
|
* failure. If the plain-text buffer is smaller than
|
||||||
|
* olm_decrypt_max_plaintext_length() then olm_session_last_error()
|
||||||
|
* will be "OUTPUT_BUFFER_TOO_SMALL". If the base64 couldn't be decoded then
|
||||||
|
* olm_session_last_error() will be "INVALID_BASE64". If the message is for
|
||||||
|
* an unsupported version of the protocol then olm_session_last_error() will
|
||||||
|
* be "BAD_MESSAGE_VERSION". If the message couldn't be decoded then
|
||||||
|
* olm_session_last_error() will be BAD_MESSAGE_FORMAT".
|
||||||
|
* If the MAC on the message was invalid then olm_session_last_error() will
|
||||||
|
* be "BAD_MESSAGE_MAC". */
|
||||||
|
size_t olm_decrypt(
|
||||||
|
OlmSession * session,
|
||||||
|
size_t message_type,
|
||||||
|
void * message, size_t message_length,
|
||||||
|
void * plaintext, size_t max_plaintext_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The length of the buffer needed to hold the SHA-256 hash. */
|
||||||
|
size_t olm_sha256_length(
|
||||||
|
OlmUtility * utility
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Calculates the SHA-256 hash of the input and encodes it as base64. If the
|
||||||
|
* output buffer is smaller than olm_sha256_length() then
|
||||||
|
* olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */
|
||||||
|
size_t olm_sha256(
|
||||||
|
OlmUtility * utility,
|
||||||
|
void const * input, size_t input_length,
|
||||||
|
void * output, size_t output_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Verify an ed25519 signature. If the key was too small then
|
||||||
|
* olm_session_last_error will be "INVALID_BASE64". If the signature was invalid
|
||||||
|
* then olm_session_last_error() will be "BAD_MESSAGE_MAC". */
|
||||||
|
size_t olm_ed25519_verify(
|
||||||
|
OlmUtility * utility,
|
||||||
|
void const * key, size_t key_length,
|
||||||
|
void const * message, size_t message_length,
|
||||||
|
void * signature, size_t signature_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the log level. By default, 1, which logs only FATAL messages.
|
||||||
|
*/
|
||||||
|
void olm_set_log_level(
|
||||||
|
unsigned int level
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OLM_HH_ */
|
|
@ -1,429 +1,4 @@
|
||||||
/* Copyright 2015, 2016 OpenMarket Ltd
|
/* this file exists only for compatibility with existing applications.
|
||||||
*
|
* You should use "#include <olm/olm.h>" instead.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
#ifndef OLM_HH_
|
#include "olm/olm.h"
|
||||||
#define OLM_HH_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const size_t OLM_MESSAGE_TYPE_PRE_KEY = 0;
|
|
||||||
static const size_t OLM_MESSAGE_TYPE_MESSAGE = 1;
|
|
||||||
|
|
||||||
typedef struct OlmAccount OlmAccount;
|
|
||||||
typedef struct OlmSession OlmSession;
|
|
||||||
typedef struct OlmUtility OlmUtility;
|
|
||||||
|
|
||||||
/** The size of an account object in bytes */
|
|
||||||
size_t olm_account_size();
|
|
||||||
|
|
||||||
/** The size of a session object in bytes */
|
|
||||||
size_t olm_session_size();
|
|
||||||
|
|
||||||
/** The size of a utility object in bytes */
|
|
||||||
size_t olm_utility_size();
|
|
||||||
|
|
||||||
/** Initialise an account object using the supplied memory
|
|
||||||
* The supplied memory must be at least olm_account_size() bytes */
|
|
||||||
OlmAccount * olm_account(
|
|
||||||
void * memory
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Initialise a session object using the supplied memory
|
|
||||||
* The supplied memory must be at least olm_session_size() bytes */
|
|
||||||
OlmSession * olm_session(
|
|
||||||
void * memory
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Initialise a utility object using the supplied memory
|
|
||||||
* The supplied memory must be at least olm_utility_size() bytes */
|
|
||||||
OlmUtility * olm_utility(
|
|
||||||
void * memory
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The value that olm will return from a function if there was an error */
|
|
||||||
size_t olm_error();
|
|
||||||
|
|
||||||
/** A null terminated string describing the most recent error to happen to an
|
|
||||||
* account */
|
|
||||||
const char * olm_account_last_error(
|
|
||||||
OlmAccount * account
|
|
||||||
);
|
|
||||||
|
|
||||||
/** A null terminated string describing the most recent error to happen to a
|
|
||||||
* session */
|
|
||||||
const char * olm_session_last_error(
|
|
||||||
OlmSession * session
|
|
||||||
);
|
|
||||||
|
|
||||||
/** A null terminated string describing the most recent error to happen to a
|
|
||||||
* utility */
|
|
||||||
const char * olm_utility_last_error(
|
|
||||||
OlmUtility * utility
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Clears the memory used to back this account */
|
|
||||||
size_t olm_clear_account(
|
|
||||||
OlmAccount * account
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Clears the memory used to back this session */
|
|
||||||
size_t olm_clear_session(
|
|
||||||
OlmSession * session
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Clears the memory used to back this utility */
|
|
||||||
size_t olm_clear_utility(
|
|
||||||
OlmUtility * utility
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Returns the number of bytes needed to store an account */
|
|
||||||
size_t olm_pickle_account_length(
|
|
||||||
OlmAccount * account
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Returns the number of bytes needed to store a session */
|
|
||||||
size_t olm_pickle_session_length(
|
|
||||||
OlmSession * session
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Stores an account as a base64 string. Encrypts the account using the
|
|
||||||
* supplied key. Returns the length of the pickled account on success.
|
|
||||||
* Returns olm_error() on failure. If the pickle output buffer
|
|
||||||
* is smaller than olm_pickle_account_length() then
|
|
||||||
* olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
|
|
||||||
size_t olm_pickle_account(
|
|
||||||
OlmAccount * account,
|
|
||||||
void const * key, size_t key_length,
|
|
||||||
void * pickled, size_t pickled_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Stores a session as a base64 string. Encrypts the session using the
|
|
||||||
* supplied key. Returns the length of the pickled session on success.
|
|
||||||
* Returns olm_error() on failure. If the pickle output buffer
|
|
||||||
* is smaller than olm_pickle_session_length() then
|
|
||||||
* olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
|
|
||||||
size_t olm_pickle_session(
|
|
||||||
OlmSession * session,
|
|
||||||
void const * key, size_t key_length,
|
|
||||||
void * pickled, size_t pickled_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Loads an account from a pickled base64 string. Decrypts the account using
|
|
||||||
* the supplied key. Returns olm_error() on failure. If the key doesn't
|
|
||||||
* match the one used to encrypt the account then olm_account_last_error()
|
|
||||||
* will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
|
|
||||||
* olm_account_last_error() will be "INVALID_BASE64". The input pickled
|
|
||||||
* buffer is destroyed */
|
|
||||||
size_t olm_unpickle_account(
|
|
||||||
OlmAccount * account,
|
|
||||||
void const * key, size_t key_length,
|
|
||||||
void * pickled, size_t pickled_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Loads a session from a pickled base64 string. Decrypts the session using
|
|
||||||
* the supplied key. Returns olm_error() on failure. If the key doesn't
|
|
||||||
* match the one used to encrypt the account then olm_session_last_error()
|
|
||||||
* will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
|
|
||||||
* olm_session_last_error() will be "INVALID_BASE64". The input pickled
|
|
||||||
* buffer is destroyed */
|
|
||||||
size_t olm_unpickle_session(
|
|
||||||
OlmSession * session,
|
|
||||||
void const * key, size_t key_length,
|
|
||||||
void * pickled, size_t pickled_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The number of random bytes needed to create an account.*/
|
|
||||||
size_t olm_create_account_random_length(
|
|
||||||
OlmAccount * account
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Creates a new account. Returns olm_error() on failure. If weren't
|
|
||||||
* enough random bytes then olm_account_last_error() will be
|
|
||||||
* "NOT_ENOUGH_RANDOM" */
|
|
||||||
size_t olm_create_account(
|
|
||||||
OlmAccount * account,
|
|
||||||
void * random, size_t random_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The size of the output buffer needed to hold the identity keys */
|
|
||||||
size_t olm_account_identity_keys_length(
|
|
||||||
OlmAccount * account
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Writes the public parts of the identity keys for the account into the
|
|
||||||
* identity_keys output buffer. Returns olm_error() on failure. If the
|
|
||||||
* identity_keys buffer was too small then olm_account_last_error() will be
|
|
||||||
* "OUTPUT_BUFFER_TOO_SMALL". */
|
|
||||||
size_t olm_account_identity_keys(
|
|
||||||
OlmAccount * account,
|
|
||||||
void * identity_keys, size_t identity_key_length
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/** The length of an ed25519 signature encoded as base64. */
|
|
||||||
size_t olm_account_signature_length(
|
|
||||||
OlmAccount * account
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Signs a message with the ed25519 key for this account. Returns olm_error()
|
|
||||||
* on failure. If the signature buffer was too small then
|
|
||||||
* olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
|
|
||||||
size_t olm_account_sign(
|
|
||||||
OlmAccount * account,
|
|
||||||
void const * message, size_t message_length,
|
|
||||||
void * signature, size_t signature_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The size of the output buffer needed to hold the one time keys */
|
|
||||||
size_t olm_account_one_time_keys_length(
|
|
||||||
OlmAccount * account
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Writes the public parts of the unpublished one time keys for the account
|
|
||||||
* into the one_time_keys output buffer. Returns olm_error() on failure.
|
|
||||||
* If the one_time_keys buffer was too small then olm_account_last_error()
|
|
||||||
* will be "OUTPUT_BUFFER_TOO_SMALL". */
|
|
||||||
size_t olm_account_one_time_keys(
|
|
||||||
OlmAccount * account,
|
|
||||||
void * one_time_keys, size_t one_time_keys_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Marks the current set of one time keys as being published. */
|
|
||||||
size_t olm_account_mark_keys_as_published(
|
|
||||||
OlmAccount * account
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The largest number of one time keys this account can store. */
|
|
||||||
size_t olm_account_max_number_of_one_time_keys(
|
|
||||||
OlmAccount * account
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The number of random bytes needed to generate a given number of new one
|
|
||||||
* time keys. */
|
|
||||||
size_t olm_account_generate_one_time_keys_random_length(
|
|
||||||
OlmAccount * account,
|
|
||||||
size_t number_of_keys
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Generates a number of new one time keys. If the total number of keys stored
|
|
||||||
* by this account exceeds max_number_of_one_time_keys() then the old keys are
|
|
||||||
* discarded. Returns olm_error() on error. If the number of random bytes is
|
|
||||||
* too small then olm_account_last_error() will be "NOT_ENOUGH_RANDOM". */
|
|
||||||
size_t olm_account_generate_one_time_keys(
|
|
||||||
OlmAccount * account,
|
|
||||||
size_t number_of_keys,
|
|
||||||
void * random, size_t random_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The number of random bytes needed to create an outbound session */
|
|
||||||
size_t olm_create_outbound_session_random_length(
|
|
||||||
OlmSession * session
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Creates a new out-bound session for sending messages to a given identity_key
|
|
||||||
* and one_time_key. Returns olm_error() on failure. If the keys couldn't be
|
|
||||||
* decoded as base64 then olm_session_last_error() will be "INVALID_BASE64"
|
|
||||||
* If there weren't enough random bytes then olm_session_last_error() will
|
|
||||||
* be "NOT_ENOUGH_RANDOM". */
|
|
||||||
size_t olm_create_outbound_session(
|
|
||||||
OlmSession * session,
|
|
||||||
OlmAccount * account,
|
|
||||||
void const * their_identity_key, size_t their_identity_key_length,
|
|
||||||
void const * their_one_time_key, size_t their_one_time_key_length,
|
|
||||||
void * random, size_t random_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Create a new in-bound session for sending/receiving messages from an
|
|
||||||
* incoming PRE_KEY message. Returns olm_error() on failure. If the base64
|
|
||||||
* couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
|
|
||||||
* If the message was for an unsupported protocol version then
|
|
||||||
* olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
|
|
||||||
* couldn't be decoded then then olm_session_last_error() will be
|
|
||||||
* "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time
|
|
||||||
* key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */
|
|
||||||
size_t olm_create_inbound_session(
|
|
||||||
OlmSession * session,
|
|
||||||
OlmAccount * account,
|
|
||||||
void * one_time_key_message, size_t message_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Create a new in-bound session for sending/receiving messages from an
|
|
||||||
* incoming PRE_KEY message. Returns olm_error() on failure. If the base64
|
|
||||||
* couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
|
|
||||||
* If the message was for an unsupported protocol version then
|
|
||||||
* olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
|
|
||||||
* couldn't be decoded then then olm_session_last_error() will be
|
|
||||||
* "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time
|
|
||||||
* key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */
|
|
||||||
size_t olm_create_inbound_session_from(
|
|
||||||
OlmSession * session,
|
|
||||||
OlmAccount * account,
|
|
||||||
void const * their_identity_key, size_t their_identity_key_length,
|
|
||||||
void * one_time_key_message, size_t message_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The length of the buffer needed to return the id for this session. */
|
|
||||||
size_t olm_session_id_length(
|
|
||||||
OlmSession * session
|
|
||||||
);
|
|
||||||
|
|
||||||
/** An identifier for this session. Will be the same for both ends of the
|
|
||||||
* conversation. If the id buffer is too small then olm_session_last_error()
|
|
||||||
* will be "OUTPUT_BUFFER_TOO_SMALL". */
|
|
||||||
size_t olm_session_id(
|
|
||||||
OlmSession * session,
|
|
||||||
void * id, size_t id_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Checks if the PRE_KEY message is for this in-bound session. This can happen
|
|
||||||
* if multiple messages are sent to this account before this account sends a
|
|
||||||
* message in reply. Returns olm_error() on failure. If the base64
|
|
||||||
* couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
|
|
||||||
* If the message was for an unsupported protocol version then
|
|
||||||
* olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
|
|
||||||
* couldn't be decoded then then olm_session_last_error() will be
|
|
||||||
* "BAD_MESSAGE_FORMAT". */
|
|
||||||
size_t olm_matches_inbound_session(
|
|
||||||
OlmSession * session,
|
|
||||||
void * one_time_key_message, size_t message_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Checks if the PRE_KEY message is for this in-bound session. This can happen
|
|
||||||
* if multiple messages are sent to this account before this account sends a
|
|
||||||
* message in reply. Returns olm_error() on failure. If the base64
|
|
||||||
* couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
|
|
||||||
* If the message was for an unsupported protocol version then
|
|
||||||
* olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
|
|
||||||
* couldn't be decoded then then olm_session_last_error() will be
|
|
||||||
* "BAD_MESSAGE_FORMAT". */
|
|
||||||
size_t olm_matches_inbound_session_from(
|
|
||||||
OlmSession * session,
|
|
||||||
void const * their_identity_key, size_t their_identity_key_length,
|
|
||||||
void * one_time_key_message, size_t message_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Removes the one time keys that the session used from the account. Returns
|
|
||||||
* olm_error() on failure. If the account doesn't have any matching one time
|
|
||||||
* keys then olm_account_last_error() will be "BAD_MESSAGE_KEY_ID". */
|
|
||||||
size_t olm_remove_one_time_keys(
|
|
||||||
OlmAccount * account,
|
|
||||||
OlmSession * session
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The type of the next message that olm_encrypt() will return. Returns
|
|
||||||
* OLM_MESSAGE_TYPE_PRE_KEY if the message will be a PRE_KEY message.
|
|
||||||
* Returns OLM_MESSAGE_TYPE_MESSAGE if the message will be a normal message.
|
|
||||||
* Returns olm_error on failure. */
|
|
||||||
size_t olm_encrypt_message_type(
|
|
||||||
OlmSession * session
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The number of random bytes needed to encrypt the next message. */
|
|
||||||
size_t olm_encrypt_random_length(
|
|
||||||
OlmSession * session
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The size of the next message in bytes for the given number of plain-text
|
|
||||||
* bytes. */
|
|
||||||
size_t olm_encrypt_message_length(
|
|
||||||
OlmSession * session,
|
|
||||||
size_t plaintext_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Encrypts a message using the session. Returns the length of the message in
|
|
||||||
* bytes on success. Writes the message as base64 into the message buffer.
|
|
||||||
* Returns olm_error() on failure. If the message buffer is too small then
|
|
||||||
* olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If there
|
|
||||||
* weren't enough random bytes then olm_session_last_error() will be
|
|
||||||
* "NOT_ENOUGH_RANDOM". */
|
|
||||||
size_t olm_encrypt(
|
|
||||||
OlmSession * session,
|
|
||||||
void const * plaintext, size_t plaintext_length,
|
|
||||||
void * random, size_t random_length,
|
|
||||||
void * message, size_t message_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The maximum number of bytes of plain-text a given message could decode to.
|
|
||||||
* The actual size could be different due to padding. The input message buffer
|
|
||||||
* is destroyed. Returns olm_error() on failure. If the message base64
|
|
||||||
* couldn't be decoded then olm_session_last_error() will be
|
|
||||||
* "INVALID_BASE64". If the message is for an unsupported version of the
|
|
||||||
* protocol then olm_session_last_error() will be "BAD_MESSAGE_VERSION".
|
|
||||||
* If the message couldn't be decoded then olm_session_last_error() will be
|
|
||||||
* "BAD_MESSAGE_FORMAT". */
|
|
||||||
size_t olm_decrypt_max_plaintext_length(
|
|
||||||
OlmSession * session,
|
|
||||||
size_t message_type,
|
|
||||||
void * message, size_t message_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Decrypts a message using the session. The input message buffer is destroyed.
|
|
||||||
* Returns the length of the plain-text on success. Returns olm_error() on
|
|
||||||
* failure. If the plain-text buffer is smaller than
|
|
||||||
* olm_decrypt_max_plaintext_length() then olm_session_last_error()
|
|
||||||
* will be "OUTPUT_BUFFER_TOO_SMALL". If the base64 couldn't be decoded then
|
|
||||||
* olm_session_last_error() will be "INVALID_BASE64". If the message is for
|
|
||||||
* an unsupported version of the protocol then olm_session_last_error() will
|
|
||||||
* be "BAD_MESSAGE_VERSION". If the message couldn't be decoded then
|
|
||||||
* olm_session_last_error() will be BAD_MESSAGE_FORMAT".
|
|
||||||
* If the MAC on the message was invalid then olm_session_last_error() will
|
|
||||||
* be "BAD_MESSAGE_MAC". */
|
|
||||||
size_t olm_decrypt(
|
|
||||||
OlmSession * session,
|
|
||||||
size_t message_type,
|
|
||||||
void * message, size_t message_length,
|
|
||||||
void * plaintext, size_t max_plaintext_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** The length of the buffer needed to hold the SHA-256 hash. */
|
|
||||||
size_t olm_sha256_length(
|
|
||||||
OlmUtility * utility
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Calculates the SHA-256 hash of the input and encodes it as base64. If the
|
|
||||||
* output buffer is smaller than olm_sha256_length() then
|
|
||||||
* olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */
|
|
||||||
size_t olm_sha256(
|
|
||||||
OlmUtility * utility,
|
|
||||||
void const * input, size_t input_length,
|
|
||||||
void * output, size_t output_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Verify an ed25519 signature. If the key was too small then
|
|
||||||
* olm_session_last_error will be "INVALID_BASE64". If the signature was invalid
|
|
||||||
* then olm_session_last_error() will be "BAD_MESSAGE_MAC". */
|
|
||||||
size_t olm_ed25519_verify(
|
|
||||||
OlmUtility * utility,
|
|
||||||
void const * key, size_t key_length,
|
|
||||||
void const * message, size_t message_length,
|
|
||||||
void * signature, size_t signature_length
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the log level. By default, 1, which logs only FATAL messages.
|
|
||||||
*/
|
|
||||||
void olm_set_log_level(
|
|
||||||
unsigned int level
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* OLM_HH_ */
|
|
||||||
|
|
50
include/olm/pickle.h
Normal file
50
include/olm/pickle.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/* Copyright 2015-2016 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef OLM_PICKLE_H_
|
||||||
|
#define OLM_PICKLE_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _olm_pickle_uint32_length(value) 4
|
||||||
|
uint8_t * _olm_pickle_uint32(uint8_t * pos, uint32_t value);
|
||||||
|
uint8_t const * _olm_unpickle_uint32(
|
||||||
|
uint8_t const * pos, uint8_t const * end,
|
||||||
|
uint32_t *value
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#define _olm_pickle_bool_length(value) 1
|
||||||
|
uint8_t * _olm_pickle_bool(uint8_t * pos, int value);
|
||||||
|
uint8_t const * _olm_unpickle_bool(
|
||||||
|
uint8_t const * pos, uint8_t const * end,
|
||||||
|
int *value
|
||||||
|
);
|
||||||
|
|
||||||
|
#define _olm_pickle_bytes_length(bytes, bytes_length) (bytes_length)
|
||||||
|
uint8_t * _olm_pickle_bytes(uint8_t * pos, uint8_t const * bytes,
|
||||||
|
size_t bytes_length);
|
||||||
|
uint8_t const * _olm_unpickle_bytes(uint8_t const * pos, uint8_t const * end,
|
||||||
|
uint8_t * bytes, size_t bytes_length);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OLM_PICKLE_H */
|
|
@ -15,12 +15,12 @@
|
||||||
|
|
||||||
#include "olm/crypto.hh"
|
#include "olm/crypto.hh"
|
||||||
#include "olm/list.hh"
|
#include "olm/list.hh"
|
||||||
#include "olm/error.hh"
|
#include "olm/error.h"
|
||||||
|
|
||||||
|
struct _olm_cipher;
|
||||||
|
|
||||||
namespace olm {
|
namespace olm {
|
||||||
|
|
||||||
class Cipher;
|
|
||||||
|
|
||||||
typedef std::uint8_t SharedKey[olm::KEY_LENGTH];
|
typedef std::uint8_t SharedKey[olm::KEY_LENGTH];
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,17 +69,17 @@ struct Ratchet {
|
||||||
|
|
||||||
Ratchet(
|
Ratchet(
|
||||||
KdfInfo const & kdf_info,
|
KdfInfo const & kdf_info,
|
||||||
Cipher const & ratchet_cipher
|
_olm_cipher const *ratchet_cipher
|
||||||
);
|
);
|
||||||
|
|
||||||
/** A some strings identifying the application to feed into the KDF. */
|
/** A some strings identifying the application to feed into the KDF. */
|
||||||
KdfInfo const & kdf_info;
|
KdfInfo const & kdf_info;
|
||||||
|
|
||||||
/** The AEAD cipher to use for encrypting messages. */
|
/** The AEAD cipher to use for encrypting messages. */
|
||||||
Cipher const & ratchet_cipher;
|
_olm_cipher const *ratchet_cipher;
|
||||||
|
|
||||||
/** The last error that happened encrypting or decrypting a message. */
|
/** The last error that happened encrypting or decrypting a message. */
|
||||||
ErrorCode last_error;
|
OlmErrorCode last_error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A count of the number of times the root key has been advanced; this is
|
* A count of the number of times the root key has been advanced; this is
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct Session {
|
||||||
Session();
|
Session();
|
||||||
|
|
||||||
Ratchet ratchet;
|
Ratchet ratchet;
|
||||||
ErrorCode last_error;
|
OlmErrorCode last_error;
|
||||||
|
|
||||||
bool received_message;
|
bool received_message;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#ifndef UTILITY_HH_
|
#ifndef UTILITY_HH_
|
||||||
#define UTILITY_HH_
|
#define UTILITY_HH_
|
||||||
|
|
||||||
#include "olm/error.hh"
|
#include "olm/error.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -29,7 +29,7 @@ struct Utility {
|
||||||
|
|
||||||
Utility();
|
Utility();
|
||||||
|
|
||||||
ErrorCode last_error;
|
OlmErrorCode last_error;
|
||||||
|
|
||||||
/** The length of a SHA-256 hash in bytes. */
|
/** The length of a SHA-256 hash in bytes. */
|
||||||
std::size_t sha256_length();
|
std::size_t sha256_length();
|
||||||
|
|
|
@ -22,7 +22,7 @@ static const char *LOG_CATEGORY = "olm::Account";
|
||||||
|
|
||||||
olm::Account::Account(
|
olm::Account::Account(
|
||||||
) : next_one_time_key_id(0),
|
) : next_one_time_key_id(0),
|
||||||
last_error(olm::ErrorCode::SUCCESS) {
|
last_error(OlmErrorCode::OLM_SUCCESS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ std::size_t olm::Account::new_account(
|
||||||
uint8_t const * random, std::size_t random_length
|
uint8_t const * random, std::size_t random_length
|
||||||
) {
|
) {
|
||||||
if (random_length < new_account_random_length()) {
|
if (random_length < new_account_random_length()) {
|
||||||
last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM;
|
last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ std::size_t olm::Account::get_identity_json(
|
||||||
size_t expected_length = get_identity_json_length();
|
size_t expected_length = get_identity_json_length();
|
||||||
|
|
||||||
if (identity_json_length < expected_length) {
|
if (identity_json_length < expected_length) {
|
||||||
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ std::size_t olm::Account::sign(
|
||||||
std::uint8_t * signature, std::size_t signature_length
|
std::uint8_t * signature, std::size_t signature_length
|
||||||
) {
|
) {
|
||||||
if (signature_length < this->signature_length()) {
|
if (signature_length < this->signature_length()) {
|
||||||
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
olm::ed25519_sign(
|
olm::ed25519_sign(
|
||||||
|
@ -192,7 +192,7 @@ std::size_t olm::Account::get_one_time_keys_json(
|
||||||
) {
|
) {
|
||||||
std::uint8_t * pos = one_time_json;
|
std::uint8_t * pos = one_time_json;
|
||||||
if (one_time_json_length < get_one_time_keys_json_length()) {
|
if (one_time_json_length < get_one_time_keys_json_length()) {
|
||||||
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
*(pos++) = '{';
|
*(pos++) = '{';
|
||||||
|
@ -253,7 +253,7 @@ std::size_t olm::Account::generate_one_time_keys(
|
||||||
std::uint8_t const * random, std::size_t random_length
|
std::uint8_t const * random, std::size_t random_length
|
||||||
) {
|
) {
|
||||||
if (random_length < generate_one_time_keys_random_length(number_of_keys)) {
|
if (random_length < generate_one_time_keys_random_length(number_of_keys)) {
|
||||||
last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM;
|
last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < number_of_keys; ++i) {
|
for (unsigned i = 0; i < number_of_keys; ++i) {
|
||||||
|
@ -368,7 +368,7 @@ std::uint8_t const * olm::unpickle(
|
||||||
uint32_t pickle_version;
|
uint32_t pickle_version;
|
||||||
pos = olm::unpickle(pos, end, pickle_version);
|
pos = olm::unpickle(pos, end, pickle_version);
|
||||||
if (pickle_version != ACCOUNT_PICKLE_VERSION) {
|
if (pickle_version != ACCOUNT_PICKLE_VERSION) {
|
||||||
value.last_error = olm::ErrorCode::UNKNOWN_PICKLE_VERSION;
|
value.last_error = OlmErrorCode::OLM_UNKNOWN_PICKLE_VERSION;
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
pos = olm::unpickle(pos, end, value.identity_keys);
|
pos = olm::unpickle(pos, end, value.identity_keys);
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
#include "olm/base64.h"
|
||||||
#include "olm/base64.hh"
|
#include "olm/base64.hh"
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static const std::uint8_t ENCODE_BASE64[64] = {
|
static const std::uint8_t ENCODE_BASE64[64] = {
|
||||||
|
@ -134,3 +134,34 @@ std::uint8_t const * olm::decode_base64(
|
||||||
}
|
}
|
||||||
return input + input_length;
|
return input + input_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// implementations of base64.h
|
||||||
|
|
||||||
|
size_t _olm_encode_base64_length(
|
||||||
|
size_t input_length
|
||||||
|
) {
|
||||||
|
return olm::encode_base64_length(input_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _olm_encode_base64(
|
||||||
|
uint8_t const * input, size_t input_length,
|
||||||
|
uint8_t * output
|
||||||
|
) {
|
||||||
|
uint8_t * r = olm::encode_base64(input, input_length, output);
|
||||||
|
return r - output;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _olm_decode_base64_length(
|
||||||
|
size_t input_length
|
||||||
|
) {
|
||||||
|
return olm::decode_base64_length(input_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _olm_decode_base64(
|
||||||
|
uint8_t const * input, size_t input_length,
|
||||||
|
uint8_t * output
|
||||||
|
) {
|
||||||
|
olm::decode_base64(input, input_length, output);
|
||||||
|
return olm::decode_base64_length(input_length);
|
||||||
|
}
|
||||||
|
|
|
@ -12,15 +12,11 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "olm/cipher.hh"
|
#include "olm/cipher.h"
|
||||||
#include "olm/crypto.hh"
|
#include "olm/crypto.hh"
|
||||||
#include "olm/memory.hh"
|
#include "olm/memory.hh"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
olm::Cipher::~Cipher() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct DerivedKeys {
|
struct DerivedKeys {
|
||||||
|
@ -36,7 +32,7 @@ static void derive_keys(
|
||||||
DerivedKeys & keys
|
DerivedKeys & keys
|
||||||
) {
|
) {
|
||||||
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH + olm::IV_LENGTH];
|
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH + olm::IV_LENGTH];
|
||||||
olm::hkdf_sha256(
|
_olm_crypto_hkdf_sha256(
|
||||||
key, key_length,
|
key, key_length,
|
||||||
nullptr, 0,
|
nullptr, 0,
|
||||||
kdf_info, kdf_info_length,
|
kdf_info, kdf_info_length,
|
||||||
|
@ -51,47 +47,40 @@ static void derive_keys(
|
||||||
|
|
||||||
static const std::size_t MAC_LENGTH = 8;
|
static const std::size_t MAC_LENGTH = 8;
|
||||||
|
|
||||||
} // namespace
|
size_t aes_sha_256_cipher_mac_length(const struct _olm_cipher *cipher) {
|
||||||
|
|
||||||
|
|
||||||
olm::CipherAesSha256::CipherAesSha256(
|
|
||||||
std::uint8_t const * kdf_info, std::size_t kdf_info_length
|
|
||||||
) : kdf_info(kdf_info), kdf_info_length(kdf_info_length) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::size_t olm::CipherAesSha256::mac_length() const {
|
|
||||||
return MAC_LENGTH;
|
return MAC_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t aes_sha_256_cipher_encrypt_ciphertext_length(
|
||||||
std::size_t olm::CipherAesSha256::encrypt_ciphertext_length(
|
const struct _olm_cipher *cipher, size_t plaintext_length
|
||||||
std::size_t plaintext_length
|
) {
|
||||||
) const {
|
|
||||||
return olm::aes_encrypt_cbc_length(plaintext_length);
|
return olm::aes_encrypt_cbc_length(plaintext_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t aes_sha_256_cipher_encrypt(
|
||||||
|
const struct _olm_cipher *cipher,
|
||||||
|
uint8_t const * key, size_t key_length,
|
||||||
|
uint8_t const * plaintext, size_t plaintext_length,
|
||||||
|
uint8_t * ciphertext, size_t ciphertext_length,
|
||||||
|
uint8_t * output, size_t output_length
|
||||||
|
) {
|
||||||
|
auto *c = reinterpret_cast<const _olm_cipher_aes_sha_256 *>(cipher);
|
||||||
|
|
||||||
std::size_t olm::CipherAesSha256::encrypt(
|
if (aes_sha_256_cipher_encrypt_ciphertext_length(cipher, plaintext_length)
|
||||||
std::uint8_t const * key, std::size_t key_length,
|
< ciphertext_length) {
|
||||||
std::uint8_t const * plaintext, std::size_t plaintext_length,
|
|
||||||
std::uint8_t * ciphertext, std::size_t ciphertext_length,
|
|
||||||
std::uint8_t * output, std::size_t output_length
|
|
||||||
) const {
|
|
||||||
if (encrypt_ciphertext_length(plaintext_length) < ciphertext_length) {
|
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
struct DerivedKeys keys;
|
|
||||||
std::uint8_t mac[olm::SHA256_OUTPUT_LENGTH];
|
|
||||||
|
|
||||||
derive_keys(kdf_info, kdf_info_length, key, key_length, keys);
|
struct DerivedKeys keys;
|
||||||
|
std::uint8_t mac[SHA256_OUTPUT_LENGTH];
|
||||||
|
|
||||||
|
derive_keys(c->kdf_info, c->kdf_info_length, key, key_length, keys);
|
||||||
|
|
||||||
olm::aes_encrypt_cbc(
|
olm::aes_encrypt_cbc(
|
||||||
keys.aes_key, keys.aes_iv, plaintext, plaintext_length, ciphertext
|
keys.aes_key, keys.aes_iv, plaintext, plaintext_length, ciphertext
|
||||||
);
|
);
|
||||||
|
|
||||||
olm::hmac_sha256(
|
_olm_crypto_hmac_sha256(
|
||||||
keys.mac_key, olm::KEY_LENGTH, output, output_length - MAC_LENGTH, mac
|
keys.mac_key, olm::KEY_LENGTH, output, output_length - MAC_LENGTH, mac
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -102,24 +91,28 @@ std::size_t olm::CipherAesSha256::encrypt(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::size_t olm::CipherAesSha256::decrypt_max_plaintext_length(
|
size_t aes_sha_256_cipher_decrypt_max_plaintext_length(
|
||||||
std::size_t ciphertext_length
|
const struct _olm_cipher *cipher,
|
||||||
) const {
|
size_t ciphertext_length
|
||||||
|
) {
|
||||||
return ciphertext_length;
|
return ciphertext_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t olm::CipherAesSha256::decrypt(
|
size_t aes_sha_256_cipher_decrypt(
|
||||||
std::uint8_t const * key, std::size_t key_length,
|
const struct _olm_cipher *cipher,
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
uint8_t const * key, size_t key_length,
|
||||||
std::uint8_t const * ciphertext, std::size_t ciphertext_length,
|
uint8_t const * input, size_t input_length,
|
||||||
std::uint8_t * plaintext, std::size_t max_plaintext_length
|
uint8_t const * ciphertext, size_t ciphertext_length,
|
||||||
) const {
|
uint8_t * plaintext, size_t max_plaintext_length
|
||||||
|
) {
|
||||||
|
auto *c = reinterpret_cast<const _olm_cipher_aes_sha_256 *>(cipher);
|
||||||
|
|
||||||
DerivedKeys keys;
|
DerivedKeys keys;
|
||||||
std::uint8_t mac[olm::SHA256_OUTPUT_LENGTH];
|
std::uint8_t mac[SHA256_OUTPUT_LENGTH];
|
||||||
|
|
||||||
derive_keys(kdf_info, kdf_info_length, key, key_length, keys);
|
derive_keys(c->kdf_info, c->kdf_info_length, key, key_length, keys);
|
||||||
|
|
||||||
olm::hmac_sha256(
|
_olm_crypto_hmac_sha256(
|
||||||
keys.mac_key, olm::KEY_LENGTH, input, input_length - MAC_LENGTH, mac
|
keys.mac_key, olm::KEY_LENGTH, input, input_length - MAC_LENGTH, mac
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -136,3 +129,13 @@ std::size_t olm::CipherAesSha256::decrypt(
|
||||||
olm::unset(keys);
|
olm::unset(keys);
|
||||||
return plaintext_length;
|
return plaintext_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
const struct _olm_cipher_ops _olm_cipher_aes_sha_256_ops = {
|
||||||
|
aes_sha_256_cipher_mac_length,
|
||||||
|
aes_sha_256_cipher_encrypt_ciphertext_length,
|
||||||
|
aes_sha_256_cipher_encrypt,
|
||||||
|
aes_sha_256_cipher_decrypt_max_plaintext_length,
|
||||||
|
aes_sha_256_cipher_decrypt,
|
||||||
|
};
|
||||||
|
|
|
@ -85,7 +85,7 @@ inline static void hmac_sha256_final(
|
||||||
std::uint8_t const * hmac_key,
|
std::uint8_t const * hmac_key,
|
||||||
std::uint8_t * output
|
std::uint8_t * output
|
||||||
) {
|
) {
|
||||||
std::uint8_t o_pad[SHA256_BLOCK_LENGTH + olm::SHA256_OUTPUT_LENGTH];
|
std::uint8_t o_pad[SHA256_BLOCK_LENGTH + SHA256_OUTPUT_LENGTH];
|
||||||
std::memcpy(o_pad, hmac_key, SHA256_BLOCK_LENGTH);
|
std::memcpy(o_pad, hmac_key, SHA256_BLOCK_LENGTH);
|
||||||
for (std::size_t i = 0; i < SHA256_BLOCK_LENGTH; ++i) {
|
for (std::size_t i = 0; i < SHA256_BLOCK_LENGTH; ++i) {
|
||||||
o_pad[i] ^= 0x5C;
|
o_pad[i] ^= 0x5C;
|
||||||
|
@ -260,7 +260,7 @@ std::size_t olm::aes_decrypt_cbc(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void olm::sha256(
|
void _olm_crypto_sha256(
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
std::uint8_t const * input, std::size_t input_length,
|
||||||
std::uint8_t * output
|
std::uint8_t * output
|
||||||
) {
|
) {
|
||||||
|
@ -272,7 +272,7 @@ void olm::sha256(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void olm::hmac_sha256(
|
void _olm_crypto_hmac_sha256(
|
||||||
std::uint8_t const * key, std::size_t key_length,
|
std::uint8_t const * key, std::size_t key_length,
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
std::uint8_t const * input, std::size_t input_length,
|
||||||
std::uint8_t * output
|
std::uint8_t * output
|
||||||
|
@ -288,7 +288,7 @@ void olm::hmac_sha256(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void olm::hkdf_sha256(
|
void _olm_crypto_hkdf_sha256(
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
std::uint8_t const * input, std::size_t input_length,
|
||||||
std::uint8_t const * salt, std::size_t salt_length,
|
std::uint8_t const * salt, std::size_t salt_length,
|
||||||
std::uint8_t const * info, std::size_t info_length,
|
std::uint8_t const * info, std::size_t info_length,
|
||||||
|
@ -296,7 +296,7 @@ void olm::hkdf_sha256(
|
||||||
) {
|
) {
|
||||||
::SHA256_CTX context;
|
::SHA256_CTX context;
|
||||||
std::uint8_t hmac_key[SHA256_BLOCK_LENGTH];
|
std::uint8_t hmac_key[SHA256_BLOCK_LENGTH];
|
||||||
std::uint8_t step_result[olm::SHA256_OUTPUT_LENGTH];
|
std::uint8_t step_result[SHA256_OUTPUT_LENGTH];
|
||||||
std::size_t bytes_remaining = output_length;
|
std::size_t bytes_remaining = output_length;
|
||||||
std::uint8_t iteration = 1;
|
std::uint8_t iteration = 1;
|
||||||
if (!salt) {
|
if (!salt) {
|
||||||
|
@ -308,20 +308,20 @@ void olm::hkdf_sha256(
|
||||||
hmac_sha256_init(&context, hmac_key);
|
hmac_sha256_init(&context, hmac_key);
|
||||||
::sha256_update(&context, input, input_length);
|
::sha256_update(&context, input, input_length);
|
||||||
hmac_sha256_final(&context, hmac_key, step_result);
|
hmac_sha256_final(&context, hmac_key, step_result);
|
||||||
hmac_sha256_key(step_result, olm::SHA256_OUTPUT_LENGTH, hmac_key);
|
hmac_sha256_key(step_result, SHA256_OUTPUT_LENGTH, hmac_key);
|
||||||
|
|
||||||
/* Expand */
|
/* Expand */
|
||||||
hmac_sha256_init(&context, hmac_key);
|
hmac_sha256_init(&context, hmac_key);
|
||||||
::sha256_update(&context, info, info_length);
|
::sha256_update(&context, info, info_length);
|
||||||
::sha256_update(&context, &iteration, 1);
|
::sha256_update(&context, &iteration, 1);
|
||||||
hmac_sha256_final(&context, hmac_key, step_result);
|
hmac_sha256_final(&context, hmac_key, step_result);
|
||||||
while (bytes_remaining > olm::SHA256_OUTPUT_LENGTH) {
|
while (bytes_remaining > SHA256_OUTPUT_LENGTH) {
|
||||||
std::memcpy(output, step_result, olm::SHA256_OUTPUT_LENGTH);
|
std::memcpy(output, step_result, SHA256_OUTPUT_LENGTH);
|
||||||
output += olm::SHA256_OUTPUT_LENGTH;
|
output += SHA256_OUTPUT_LENGTH;
|
||||||
bytes_remaining -= olm::SHA256_OUTPUT_LENGTH;
|
bytes_remaining -= SHA256_OUTPUT_LENGTH;
|
||||||
iteration ++;
|
iteration ++;
|
||||||
hmac_sha256_init(&context, hmac_key);
|
hmac_sha256_init(&context, hmac_key);
|
||||||
::sha256_update(&context, step_result, olm::SHA256_OUTPUT_LENGTH);
|
::sha256_update(&context, step_result, SHA256_OUTPUT_LENGTH);
|
||||||
::sha256_update(&context, info, info_length);
|
::sha256_update(&context, info, info_length);
|
||||||
::sha256_update(&context, &iteration, 1);
|
::sha256_update(&context, &iteration, 1);
|
||||||
hmac_sha256_final(&context, hmac_key, step_result);
|
hmac_sha256_final(&context, hmac_key, step_result);
|
||||||
|
|
|
@ -13,7 +13,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "olm/memory.hh"
|
#include "olm/memory.hh"
|
||||||
|
#include "olm/memory.h"
|
||||||
|
|
||||||
|
void _olm_unset(
|
||||||
|
void volatile * buffer, size_t buffer_length
|
||||||
|
) {
|
||||||
|
olm::unset(buffer, buffer_length);
|
||||||
|
}
|
||||||
|
|
||||||
void olm::unset(
|
void olm::unset(
|
||||||
void volatile * buffer, std::size_t buffer_length
|
void volatile * buffer, std::size_t buffer_length
|
||||||
|
|
77
src/olm.cpp
77
src/olm.cpp
|
@ -12,12 +12,12 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "olm/olm.hh"
|
#include "olm/olm.h"
|
||||||
#include "olm/session.hh"
|
#include "olm/session.hh"
|
||||||
#include "olm/account.hh"
|
#include "olm/account.hh"
|
||||||
|
#include "olm/cipher.h"
|
||||||
#include "olm/utility.hh"
|
#include "olm/utility.hh"
|
||||||
#include "olm/base64.hh"
|
#include "olm/base64.hh"
|
||||||
#include "olm/cipher.hh"
|
|
||||||
#include "olm/memory.hh"
|
#include "olm/memory.hh"
|
||||||
#include "olm/logging.h"
|
#include "olm/logging.h"
|
||||||
|
|
||||||
|
@ -58,17 +58,15 @@ static std::uint8_t const * from_c(void const * bytes) {
|
||||||
return reinterpret_cast<std::uint8_t const *>(bytes);
|
return reinterpret_cast<std::uint8_t const *>(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::uint8_t CIPHER_KDF_INFO[] = "Pickle";
|
static const struct _olm_cipher_aes_sha_256 PICKLE_CIPHER =
|
||||||
|
OLM_CIPHER_INIT_AES_SHA_256("Pickle");
|
||||||
static const olm::CipherAesSha256 PICKLE_CIPHER(
|
|
||||||
CIPHER_KDF_INFO, sizeof(CIPHER_KDF_INFO) -1
|
|
||||||
);
|
|
||||||
|
|
||||||
std::size_t enc_output_length(
|
std::size_t enc_output_length(
|
||||||
size_t raw_length
|
size_t raw_length
|
||||||
) {
|
) {
|
||||||
std::size_t length = PICKLE_CIPHER.encrypt_ciphertext_length(raw_length);
|
auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER);
|
||||||
length += PICKLE_CIPHER.mac_length();
|
std::size_t length = cipher->ops->encrypt_ciphertext_length(cipher, raw_length);
|
||||||
|
length += cipher->ops->mac_length(cipher);
|
||||||
return olm::encode_base64_length(length);
|
return olm::encode_base64_length(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,8 +75,9 @@ std::uint8_t * enc_output_pos(
|
||||||
std::uint8_t * output,
|
std::uint8_t * output,
|
||||||
size_t raw_length
|
size_t raw_length
|
||||||
) {
|
) {
|
||||||
std::size_t length = PICKLE_CIPHER.encrypt_ciphertext_length(raw_length);
|
auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER);
|
||||||
length += PICKLE_CIPHER.mac_length();
|
std::size_t length = cipher->ops->encrypt_ciphertext_length(cipher, raw_length);
|
||||||
|
length += cipher->ops->mac_length(cipher);
|
||||||
return output + olm::encode_base64_length(length) - length;
|
return output + olm::encode_base64_length(length) - length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,13 +85,15 @@ std::size_t enc_output(
|
||||||
std::uint8_t const * key, std::size_t key_length,
|
std::uint8_t const * key, std::size_t key_length,
|
||||||
std::uint8_t * output, size_t raw_length
|
std::uint8_t * output, size_t raw_length
|
||||||
) {
|
) {
|
||||||
std::size_t ciphertext_length = PICKLE_CIPHER.encrypt_ciphertext_length(
|
auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER);
|
||||||
raw_length
|
std::size_t ciphertext_length = cipher->ops->encrypt_ciphertext_length(
|
||||||
|
cipher, raw_length
|
||||||
);
|
);
|
||||||
std::size_t length = ciphertext_length + PICKLE_CIPHER.mac_length();
|
std::size_t length = ciphertext_length + cipher->ops->mac_length(cipher);
|
||||||
std::size_t base64_length = olm::encode_base64_length(length);
|
std::size_t base64_length = olm::encode_base64_length(length);
|
||||||
std::uint8_t * raw_output = output + base64_length - length;
|
std::uint8_t * raw_output = output + base64_length - length;
|
||||||
PICKLE_CIPHER.encrypt(
|
cipher->ops->encrypt(
|
||||||
|
cipher,
|
||||||
key, key_length,
|
key, key_length,
|
||||||
raw_output, raw_length,
|
raw_output, raw_length,
|
||||||
raw_output, ciphertext_length,
|
raw_output, ciphertext_length,
|
||||||
|
@ -105,23 +106,25 @@ std::size_t enc_output(
|
||||||
std::size_t enc_input(
|
std::size_t enc_input(
|
||||||
std::uint8_t const * key, std::size_t key_length,
|
std::uint8_t const * key, std::size_t key_length,
|
||||||
std::uint8_t * input, size_t b64_length,
|
std::uint8_t * input, size_t b64_length,
|
||||||
olm::ErrorCode & last_error
|
OlmErrorCode & last_error
|
||||||
) {
|
) {
|
||||||
std::size_t enc_length = olm::decode_base64_length(b64_length);
|
std::size_t enc_length = olm::decode_base64_length(b64_length);
|
||||||
if (enc_length == std::size_t(-1)) {
|
if (enc_length == std::size_t(-1)) {
|
||||||
last_error = olm::ErrorCode::INVALID_BASE64;
|
last_error = OlmErrorCode::OLM_INVALID_BASE64;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
olm::decode_base64(input, b64_length, input);
|
olm::decode_base64(input, b64_length, input);
|
||||||
std::size_t raw_length = enc_length - PICKLE_CIPHER.mac_length();
|
auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER);
|
||||||
std::size_t result = PICKLE_CIPHER.decrypt(
|
std::size_t raw_length = enc_length - cipher->ops->mac_length(cipher);
|
||||||
|
std::size_t result = cipher->ops->decrypt(
|
||||||
|
cipher,
|
||||||
key, key_length,
|
key, key_length,
|
||||||
input, enc_length,
|
input, enc_length,
|
||||||
input, raw_length,
|
input, raw_length,
|
||||||
input, raw_length
|
input, raw_length
|
||||||
);
|
);
|
||||||
if (result == std::size_t(-1)) {
|
if (result == std::size_t(-1)) {
|
||||||
last_error = olm::ErrorCode::BAD_ACCOUNT_KEY;
|
last_error = OlmErrorCode::OLM_BAD_ACCOUNT_KEY;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -151,11 +154,11 @@ std::size_t b64_output(
|
||||||
|
|
||||||
std::size_t b64_input(
|
std::size_t b64_input(
|
||||||
std::uint8_t * input, size_t b64_length,
|
std::uint8_t * input, size_t b64_length,
|
||||||
olm::ErrorCode & last_error
|
OlmErrorCode & last_error
|
||||||
) {
|
) {
|
||||||
std::size_t raw_length = olm::decode_base64_length(b64_length);
|
std::size_t raw_length = olm::decode_base64_length(b64_length);
|
||||||
if (raw_length == std::size_t(-1)) {
|
if (raw_length == std::size_t(-1)) {
|
||||||
last_error = olm::ErrorCode::INVALID_BASE64;
|
last_error = OlmErrorCode::OLM_INVALID_BASE64;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
olm::decode_base64(input, b64_length, input);
|
olm::decode_base64(input, b64_length, input);
|
||||||
|
@ -313,7 +316,7 @@ size_t olm_pickle_account(
|
||||||
olm::Account & object = *from_c(account);
|
olm::Account & object = *from_c(account);
|
||||||
std::size_t raw_length = pickle_length(object);
|
std::size_t raw_length = pickle_length(object);
|
||||||
if (pickled_length < enc_output_length(raw_length)) {
|
if (pickled_length < enc_output_length(raw_length)) {
|
||||||
object.last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
object.last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return size_t(-1);
|
return size_t(-1);
|
||||||
}
|
}
|
||||||
pickle(enc_output_pos(from_c(pickled), raw_length), object);
|
pickle(enc_output_pos(from_c(pickled), raw_length), object);
|
||||||
|
@ -329,7 +332,7 @@ size_t olm_pickle_session(
|
||||||
olm::Session & object = *from_c(session);
|
olm::Session & object = *from_c(session);
|
||||||
std::size_t raw_length = pickle_length(object);
|
std::size_t raw_length = pickle_length(object);
|
||||||
if (pickled_length < enc_output_length(raw_length)) {
|
if (pickled_length < enc_output_length(raw_length)) {
|
||||||
object.last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
object.last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return size_t(-1);
|
return size_t(-1);
|
||||||
}
|
}
|
||||||
pickle(enc_output_pos(from_c(pickled), raw_length), object);
|
pickle(enc_output_pos(from_c(pickled), raw_length), object);
|
||||||
|
@ -356,8 +359,8 @@ size_t olm_unpickle_account(
|
||||||
* (pos + raw_length). On error unpickle will return (pos + raw_length + 1).
|
* (pos + raw_length). On error unpickle will return (pos + raw_length + 1).
|
||||||
*/
|
*/
|
||||||
if (end != unpickle(pos, end + 1, object)) {
|
if (end != unpickle(pos, end + 1, object)) {
|
||||||
if (object.last_error == olm::ErrorCode::SUCCESS) {
|
if (object.last_error == OlmErrorCode::OLM_SUCCESS) {
|
||||||
object.last_error = olm::ErrorCode::CORRUPTED_PICKLE;
|
object.last_error = OlmErrorCode::OLM_CORRUPTED_PICKLE;
|
||||||
}
|
}
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
@ -385,8 +388,8 @@ size_t olm_unpickle_session(
|
||||||
* (pos + raw_length). On error unpickle will return (pos + raw_length + 1).
|
* (pos + raw_length). On error unpickle will return (pos + raw_length + 1).
|
||||||
*/
|
*/
|
||||||
if (end != unpickle(pos, end + 1, object)) {
|
if (end != unpickle(pos, end + 1, object)) {
|
||||||
if (object.last_error == olm::ErrorCode::SUCCESS) {
|
if (object.last_error == OlmErrorCode::OLM_SUCCESS) {
|
||||||
object.last_error = olm::ErrorCode::CORRUPTED_PICKLE;
|
object.last_error = OlmErrorCode::OLM_CORRUPTED_PICKLE;
|
||||||
}
|
}
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
@ -443,7 +446,7 @@ size_t olm_account_sign(
|
||||||
std::size_t raw_length = from_c(account)->signature_length();
|
std::size_t raw_length = from_c(account)->signature_length();
|
||||||
if (signature_length < b64_output_length(raw_length)) {
|
if (signature_length < b64_output_length(raw_length)) {
|
||||||
from_c(account)->last_error =
|
from_c(account)->last_error =
|
||||||
olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
from_c(account)->sign(
|
from_c(account)->sign(
|
||||||
|
@ -529,7 +532,7 @@ size_t olm_create_outbound_session(
|
||||||
if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH
|
if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH
|
||||||
|| olm::decode_base64_length(ot_key_length) != olm::KEY_LENGTH
|
|| olm::decode_base64_length(ot_key_length) != olm::KEY_LENGTH
|
||||||
) {
|
) {
|
||||||
from_c(session)->last_error = olm::ErrorCode::INVALID_BASE64;
|
from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
olm::Curve25519PublicKey identity_key;
|
olm::Curve25519PublicKey identity_key;
|
||||||
|
@ -574,7 +577,7 @@ size_t olm_create_inbound_session_from(
|
||||||
std::size_t id_key_length = their_identity_key_length;
|
std::size_t id_key_length = their_identity_key_length;
|
||||||
|
|
||||||
if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) {
|
if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) {
|
||||||
from_c(session)->last_error = olm::ErrorCode::INVALID_BASE64;
|
from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
olm::Curve25519PublicKey identity_key;
|
olm::Curve25519PublicKey identity_key;
|
||||||
|
@ -606,7 +609,7 @@ size_t olm_session_id(
|
||||||
std::size_t raw_length = from_c(session)->session_id_length();
|
std::size_t raw_length = from_c(session)->session_id_length();
|
||||||
if (id_length < b64_output_length(raw_length)) {
|
if (id_length < b64_output_length(raw_length)) {
|
||||||
from_c(session)->last_error =
|
from_c(session)->last_error =
|
||||||
olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
std::size_t result = from_c(session)->session_id(
|
std::size_t result = from_c(session)->session_id(
|
||||||
|
@ -645,7 +648,7 @@ size_t olm_matches_inbound_session_from(
|
||||||
std::size_t id_key_length = their_identity_key_length;
|
std::size_t id_key_length = their_identity_key_length;
|
||||||
|
|
||||||
if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) {
|
if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) {
|
||||||
from_c(session)->last_error = olm::ErrorCode::INVALID_BASE64;
|
from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
olm::Curve25519PublicKey identity_key;
|
olm::Curve25519PublicKey identity_key;
|
||||||
|
@ -672,7 +675,7 @@ size_t olm_remove_one_time_keys(
|
||||||
from_c(session)->bob_one_time_key
|
from_c(session)->bob_one_time_key
|
||||||
);
|
);
|
||||||
if (result == std::size_t(-1)) {
|
if (result == std::size_t(-1)) {
|
||||||
from_c(account)->last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID;
|
from_c(account)->last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -713,7 +716,7 @@ size_t olm_encrypt(
|
||||||
);
|
);
|
||||||
if (message_length < b64_output_length(raw_length)) {
|
if (message_length < b64_output_length(raw_length)) {
|
||||||
from_c(session)->last_error =
|
from_c(session)->last_error =
|
||||||
olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
std::size_t result = from_c(session)->encrypt(
|
std::size_t result = from_c(session)->encrypt(
|
||||||
|
@ -780,7 +783,7 @@ size_t olm_sha256(
|
||||||
std::size_t raw_length = from_c(utility)->sha256_length();
|
std::size_t raw_length = from_c(utility)->sha256_length();
|
||||||
if (output_length < b64_output_length(raw_length)) {
|
if (output_length < b64_output_length(raw_length)) {
|
||||||
from_c(utility)->last_error =
|
from_c(utility)->last_error =
|
||||||
olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
std::size_t result = from_c(utility)->sha256(
|
std::size_t result = from_c(utility)->sha256(
|
||||||
|
@ -801,7 +804,7 @@ size_t olm_ed25519_verify(
|
||||||
void * signature, size_t signature_length
|
void * signature, size_t signature_length
|
||||||
) {
|
) {
|
||||||
if (olm::decode_base64_length(key_length) != olm::KEY_LENGTH) {
|
if (olm::decode_base64_length(key_length) != olm::KEY_LENGTH) {
|
||||||
from_c(utility)->last_error = olm::ErrorCode::INVALID_BASE64;
|
from_c(utility)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
olm::Ed25519PublicKey verify_key;
|
olm::Ed25519PublicKey verify_key;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "olm/pickle.hh"
|
#include "olm/pickle.hh"
|
||||||
|
#include "olm/pickle.h"
|
||||||
|
|
||||||
std::uint8_t * olm::pickle(
|
std::uint8_t * olm::pickle(
|
||||||
std::uint8_t * pos,
|
std::uint8_t * pos,
|
||||||
|
@ -196,3 +197,37 @@ std::uint8_t const * olm::unpickle(
|
||||||
);
|
);
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// pickle.h implementations
|
||||||
|
|
||||||
|
uint8_t * _olm_pickle_uint32(uint8_t * pos, uint32_t value) {
|
||||||
|
return olm::pickle(pos, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t const * _olm_unpickle_uint32(
|
||||||
|
uint8_t const * pos, uint8_t const * end,
|
||||||
|
uint32_t *value
|
||||||
|
) {
|
||||||
|
return olm::unpickle(pos, end, *value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t * _olm_pickle_bool(uint8_t * pos, int value) {
|
||||||
|
return olm::pickle(pos, (bool)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t const * _olm_unpickle_bool(
|
||||||
|
uint8_t const * pos, uint8_t const * end,
|
||||||
|
int *value
|
||||||
|
) {
|
||||||
|
return olm::unpickle(pos, end, *reinterpret_cast<bool *>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t * _olm_pickle_bytes(uint8_t * pos, uint8_t const * bytes,
|
||||||
|
size_t bytes_length) {
|
||||||
|
return olm::pickle_bytes(pos, bytes, bytes_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t const * _olm_unpickle_bytes(uint8_t const * pos, uint8_t const * end,
|
||||||
|
uint8_t * bytes, size_t bytes_length) {
|
||||||
|
return olm::unpickle_bytes(pos, end, bytes, bytes_length);
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "olm/ratchet.hh"
|
#include "olm/ratchet.hh"
|
||||||
#include "olm/message.hh"
|
#include "olm/message.hh"
|
||||||
#include "olm/memory.hh"
|
#include "olm/memory.hh"
|
||||||
#include "olm/cipher.hh"
|
#include "olm/cipher.h"
|
||||||
#include "olm/pickle.hh"
|
#include "olm/pickle.hh"
|
||||||
#include "olm/logging.h"
|
#include "olm/logging.h"
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ static void create_chain_key(
|
||||||
olm::SharedKey secret;
|
olm::SharedKey secret;
|
||||||
olm::curve25519_shared_secret(our_key, their_key, secret);
|
olm::curve25519_shared_secret(our_key, their_key, secret);
|
||||||
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
|
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
|
||||||
olm::hkdf_sha256(
|
_olm_crypto_hkdf_sha256(
|
||||||
secret, sizeof(secret),
|
secret, sizeof(secret),
|
||||||
root_key, sizeof(root_key),
|
root_key, sizeof(root_key),
|
||||||
info.ratchet_info, info.ratchet_info_length,
|
info.ratchet_info, info.ratchet_info_length,
|
||||||
|
@ -73,7 +73,7 @@ static void advance_chain_key(
|
||||||
olm::ChainKey const & chain_key,
|
olm::ChainKey const & chain_key,
|
||||||
olm::ChainKey & new_chain_key
|
olm::ChainKey & new_chain_key
|
||||||
) {
|
) {
|
||||||
olm::hmac_sha256(
|
_olm_crypto_hmac_sha256(
|
||||||
chain_key.key, sizeof(chain_key.key),
|
chain_key.key, sizeof(chain_key.key),
|
||||||
CHAIN_KEY_SEED, sizeof(CHAIN_KEY_SEED),
|
CHAIN_KEY_SEED, sizeof(CHAIN_KEY_SEED),
|
||||||
new_chain_key.key
|
new_chain_key.key
|
||||||
|
@ -89,7 +89,7 @@ static void create_message_keys(
|
||||||
olm::ChainKey const & chain_key,
|
olm::ChainKey const & chain_key,
|
||||||
olm::KdfInfo const & info,
|
olm::KdfInfo const & info,
|
||||||
olm::MessageKey & message_key) {
|
olm::MessageKey & message_key) {
|
||||||
olm::hmac_sha256(
|
_olm_crypto_hmac_sha256(
|
||||||
chain_key.key, sizeof(chain_key.key),
|
chain_key.key, sizeof(chain_key.key),
|
||||||
MESSAGE_KEY_SEED, sizeof(MESSAGE_KEY_SEED),
|
MESSAGE_KEY_SEED, sizeof(MESSAGE_KEY_SEED),
|
||||||
message_key.key
|
message_key.key
|
||||||
|
@ -101,12 +101,13 @@ static void create_message_keys(
|
||||||
|
|
||||||
|
|
||||||
static std::size_t verify_mac_and_decrypt(
|
static std::size_t verify_mac_and_decrypt(
|
||||||
olm::Cipher const & cipher,
|
_olm_cipher const *cipher,
|
||||||
olm::MessageKey const & message_key,
|
olm::MessageKey const & message_key,
|
||||||
olm::MessageReader const & reader,
|
olm::MessageReader const & reader,
|
||||||
std::uint8_t * plaintext, std::size_t max_plaintext_length
|
std::uint8_t * plaintext, std::size_t max_plaintext_length
|
||||||
) {
|
) {
|
||||||
return cipher.decrypt(
|
return cipher->ops->decrypt(
|
||||||
|
cipher,
|
||||||
message_key.key, sizeof(message_key.key),
|
message_key.key, sizeof(message_key.key),
|
||||||
reader.input, reader.input_length,
|
reader.input, reader.input_length,
|
||||||
reader.ciphertext, reader.ciphertext_length,
|
reader.ciphertext, reader.ciphertext_length,
|
||||||
|
@ -193,10 +194,10 @@ static std::size_t verify_mac_and_decrypt_for_new_chain(
|
||||||
|
|
||||||
olm::Ratchet::Ratchet(
|
olm::Ratchet::Ratchet(
|
||||||
olm::KdfInfo const & kdf_info,
|
olm::KdfInfo const & kdf_info,
|
||||||
Cipher const & ratchet_cipher
|
_olm_cipher const * ratchet_cipher
|
||||||
) : kdf_info(kdf_info),
|
) : kdf_info(kdf_info),
|
||||||
ratchet_cipher(ratchet_cipher),
|
ratchet_cipher(ratchet_cipher),
|
||||||
last_error(olm::ErrorCode::SUCCESS) {
|
last_error(OlmErrorCode::OLM_SUCCESS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,7 +206,7 @@ void olm::Ratchet::initialise_as_bob(
|
||||||
olm::Curve25519PublicKey const & their_ratchet_key
|
olm::Curve25519PublicKey const & their_ratchet_key
|
||||||
) {
|
) {
|
||||||
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
|
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
|
||||||
olm::hkdf_sha256(
|
_olm_crypto_hkdf_sha256(
|
||||||
shared_secret, shared_secret_length,
|
shared_secret, shared_secret_length,
|
||||||
nullptr, 0,
|
nullptr, 0,
|
||||||
kdf_info.root_info, kdf_info.root_info_length,
|
kdf_info.root_info, kdf_info.root_info_length,
|
||||||
|
@ -228,7 +229,7 @@ void olm::Ratchet::initialise_as_alice(
|
||||||
olm::Curve25519KeyPair const & our_ratchet_key
|
olm::Curve25519KeyPair const & our_ratchet_key
|
||||||
) {
|
) {
|
||||||
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
|
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
|
||||||
olm::hkdf_sha256(
|
_olm_crypto_hkdf_sha256(
|
||||||
shared_secret, shared_secret_length,
|
shared_secret, shared_secret_length,
|
||||||
nullptr, 0,
|
nullptr, 0,
|
||||||
kdf_info.root_info, kdf_info.root_info_length,
|
kdf_info.root_info, kdf_info.root_info_length,
|
||||||
|
@ -417,11 +418,12 @@ std::size_t olm::Ratchet::encrypt_output_length(
|
||||||
if (!sender_chain.empty()) {
|
if (!sender_chain.empty()) {
|
||||||
counter = sender_chain[0].chain_key.index;
|
counter = sender_chain[0].chain_key.index;
|
||||||
}
|
}
|
||||||
std::size_t padded = ratchet_cipher.encrypt_ciphertext_length(
|
std::size_t padded = ratchet_cipher->ops->encrypt_ciphertext_length(
|
||||||
|
ratchet_cipher,
|
||||||
plaintext_length
|
plaintext_length
|
||||||
);
|
);
|
||||||
return olm::encode_message_length(
|
return olm::encode_message_length(
|
||||||
counter, olm::KEY_LENGTH, padded, ratchet_cipher.mac_length()
|
counter, olm::KEY_LENGTH, padded, ratchet_cipher->ops->mac_length(ratchet_cipher)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,11 +441,11 @@ std::size_t olm::Ratchet::encrypt(
|
||||||
std::size_t output_length = encrypt_output_length(plaintext_length);
|
std::size_t output_length = encrypt_output_length(plaintext_length);
|
||||||
|
|
||||||
if (random_length < encrypt_random_length()) {
|
if (random_length < encrypt_random_length()) {
|
||||||
last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM;
|
last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
if (max_output_length < output_length) {
|
if (max_output_length < output_length) {
|
||||||
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,7 +471,8 @@ std::size_t olm::Ratchet::encrypt(
|
||||||
create_message_keys(chain_index, sender_chain[0].chain_key, kdf_info, keys);
|
create_message_keys(chain_index, sender_chain[0].chain_key, kdf_info, keys);
|
||||||
advance_chain_key(chain_index, sender_chain[0].chain_key, sender_chain[0].chain_key);
|
advance_chain_key(chain_index, sender_chain[0].chain_key, sender_chain[0].chain_key);
|
||||||
|
|
||||||
std::size_t ciphertext_length = ratchet_cipher.encrypt_ciphertext_length(
|
std::size_t ciphertext_length = ratchet_cipher->ops->encrypt_ciphertext_length(
|
||||||
|
ratchet_cipher,
|
||||||
plaintext_length
|
plaintext_length
|
||||||
);
|
);
|
||||||
std::uint32_t counter = keys.index;
|
std::uint32_t counter = keys.index;
|
||||||
|
@ -484,7 +487,8 @@ std::size_t olm::Ratchet::encrypt(
|
||||||
|
|
||||||
olm::store_array(writer.ratchet_key, ratchet_key.public_key);
|
olm::store_array(writer.ratchet_key, ratchet_key.public_key);
|
||||||
|
|
||||||
ratchet_cipher.encrypt(
|
ratchet_cipher->ops->encrypt(
|
||||||
|
ratchet_cipher,
|
||||||
keys.key, sizeof(keys.key),
|
keys.key, sizeof(keys.key),
|
||||||
plaintext, plaintext_length,
|
plaintext, plaintext_length,
|
||||||
writer.ciphertext, ciphertext_length,
|
writer.ciphertext, ciphertext_length,
|
||||||
|
@ -509,15 +513,17 @@ std::size_t olm::Ratchet::decrypt_max_plaintext_length(
|
||||||
) {
|
) {
|
||||||
olm::MessageReader reader;
|
olm::MessageReader reader;
|
||||||
olm::decode_message(
|
olm::decode_message(
|
||||||
reader, input, input_length, ratchet_cipher.mac_length()
|
reader, input, input_length,
|
||||||
|
ratchet_cipher->ops->mac_length(ratchet_cipher)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!reader.ciphertext) {
|
if (!reader.ciphertext) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ratchet_cipher.decrypt_max_plaintext_length(reader.ciphertext_length);
|
return ratchet_cipher->ops->decrypt_max_plaintext_length(
|
||||||
|
ratchet_cipher, reader.ciphertext_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -531,30 +537,32 @@ std::size_t olm::Ratchet::decrypt(
|
||||||
|
|
||||||
olm::MessageReader reader;
|
olm::MessageReader reader;
|
||||||
olm::decode_message(
|
olm::decode_message(
|
||||||
reader, input, input_length, ratchet_cipher.mac_length()
|
reader, input, input_length,
|
||||||
|
ratchet_cipher->ops->mac_length(ratchet_cipher)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (reader.version != PROTOCOL_VERSION) {
|
if (reader.version != PROTOCOL_VERSION) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_VERSION;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_VERSION;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reader.has_counter || !reader.ratchet_key || !reader.ciphertext) {
|
if (!reader.has_counter || !reader.ratchet_key || !reader.ciphertext) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t max_length = ratchet_cipher.decrypt_max_plaintext_length(
|
std::size_t max_length = ratchet_cipher->ops->decrypt_max_plaintext_length(
|
||||||
|
ratchet_cipher,
|
||||||
reader.ciphertext_length
|
reader.ciphertext_length
|
||||||
);
|
);
|
||||||
|
|
||||||
if (max_plaintext_length < max_length) {
|
if (max_plaintext_length < max_length) {
|
||||||
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reader.ratchet_key_length != olm::KEY_LENGTH) {
|
if (reader.ratchet_key_length != olm::KEY_LENGTH) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,7 +627,7 @@ std::size_t olm::Ratchet::decrypt(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == std::size_t(-1)) {
|
if (result == std::size_t(-1)) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_MAC;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "olm/session.hh"
|
#include "olm/session.hh"
|
||||||
#include "olm/cipher.hh"
|
#include "olm/cipher.h"
|
||||||
#include "olm/crypto.hh"
|
#include "olm/crypto.hh"
|
||||||
#include "olm/account.hh"
|
#include "olm/account.hh"
|
||||||
#include "olm/logging.h"
|
#include "olm/logging.h"
|
||||||
|
@ -33,20 +33,19 @@ static const std::uint8_t ROOT_KDF_INFO[] = "OLM_ROOT";
|
||||||
static const std::uint8_t RATCHET_KDF_INFO[] = "OLM_RATCHET";
|
static const std::uint8_t RATCHET_KDF_INFO[] = "OLM_RATCHET";
|
||||||
static const std::uint8_t CIPHER_KDF_INFO[] = "OLM_KEYS";
|
static const std::uint8_t CIPHER_KDF_INFO[] = "OLM_KEYS";
|
||||||
|
|
||||||
static const olm::CipherAesSha256 OLM_CIPHER(
|
|
||||||
CIPHER_KDF_INFO, sizeof(CIPHER_KDF_INFO) -1
|
|
||||||
);
|
|
||||||
|
|
||||||
static const olm::KdfInfo OLM_KDF_INFO = {
|
static const olm::KdfInfo OLM_KDF_INFO = {
|
||||||
ROOT_KDF_INFO, sizeof(ROOT_KDF_INFO) - 1,
|
ROOT_KDF_INFO, sizeof(ROOT_KDF_INFO) - 1,
|
||||||
RATCHET_KDF_INFO, sizeof(RATCHET_KDF_INFO) - 1
|
RATCHET_KDF_INFO, sizeof(RATCHET_KDF_INFO) - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct _olm_cipher_aes_sha_256 OLM_CIPHER =
|
||||||
|
OLM_CIPHER_INIT_AES_SHA_256(CIPHER_KDF_INFO);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
olm::Session::Session(
|
olm::Session::Session(
|
||||||
) : ratchet(OLM_KDF_INFO, OLM_CIPHER),
|
) : ratchet(OLM_KDF_INFO, OLM_CIPHER_BASE(&OLM_CIPHER)),
|
||||||
last_error(olm::ErrorCode::SUCCESS),
|
last_error(OlmErrorCode::OLM_SUCCESS),
|
||||||
received_message(false) {
|
received_message(false) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -64,7 +63,7 @@ std::size_t olm::Session::new_outbound_session(
|
||||||
std::uint8_t const * random, std::size_t random_length
|
std::uint8_t const * random, std::size_t random_length
|
||||||
) {
|
) {
|
||||||
if (random_length < new_outbound_session_random_length()) {
|
if (random_length < new_outbound_session_random_length()) {
|
||||||
last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM;
|
last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +141,7 @@ std::size_t olm::Session::new_inbound_session(
|
||||||
decode_one_time_key_message(reader, one_time_key_message, message_length);
|
decode_one_time_key_message(reader, one_time_key_message, message_length);
|
||||||
|
|
||||||
if (!check_message_fields(reader, their_identity_key)) {
|
if (!check_message_fields(reader, their_identity_key)) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +157,7 @@ std::size_t olm::Session::new_inbound_session(
|
||||||
olm::bytes_to_string(reader.identity_key,
|
olm::bytes_to_string(reader.identity_key,
|
||||||
reader.identity_key + olm::KEY_LENGTH)
|
reader.identity_key + olm::KEY_LENGTH)
|
||||||
.c_str());
|
.c_str());
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,12 +176,12 @@ std::size_t olm::Session::new_inbound_session(
|
||||||
olm::MessageReader message_reader;
|
olm::MessageReader message_reader;
|
||||||
decode_message(
|
decode_message(
|
||||||
message_reader, reader.message, reader.message_length,
|
message_reader, reader.message, reader.message_length,
|
||||||
ratchet.ratchet_cipher.mac_length()
|
ratchet.ratchet_cipher->ops->mac_length(ratchet.ratchet_cipher)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!message_reader.ratchet_key
|
if (!message_reader.ratchet_key
|
||||||
|| message_reader.ratchet_key_length != olm::KEY_LENGTH) {
|
|| message_reader.ratchet_key_length != olm::KEY_LENGTH) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +199,7 @@ std::size_t olm::Session::new_inbound_session(
|
||||||
olm_logf(OLM_LOG_INFO, LOG_CATEGORY,
|
olm_logf(OLM_LOG_INFO, LOG_CATEGORY,
|
||||||
"Session uses unknown ephemeral key %s",
|
"Session uses unknown ephemeral key %s",
|
||||||
bob_one_time_key.to_string().c_str());
|
bob_one_time_key.to_string().c_str());
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +226,7 @@ std::size_t olm::Session::new_inbound_session(
|
||||||
|
|
||||||
|
|
||||||
std::size_t olm::Session::session_id_length() {
|
std::size_t olm::Session::session_id_length() {
|
||||||
return olm::SHA256_OUTPUT_LENGTH;
|
return SHA256_OUTPUT_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -235,7 +234,7 @@ std::size_t olm::Session::session_id(
|
||||||
std::uint8_t * id, std::size_t id_length
|
std::uint8_t * id, std::size_t id_length
|
||||||
) {
|
) {
|
||||||
if (id_length < session_id_length()) {
|
if (id_length < session_id_length()) {
|
||||||
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
std::uint8_t tmp[olm::KEY_LENGTH * 3];
|
std::uint8_t tmp[olm::KEY_LENGTH * 3];
|
||||||
|
@ -243,7 +242,7 @@ std::size_t olm::Session::session_id(
|
||||||
pos = olm::store_array(pos, alice_identity_key.public_key);
|
pos = olm::store_array(pos, alice_identity_key.public_key);
|
||||||
pos = olm::store_array(pos, alice_base_key.public_key);
|
pos = olm::store_array(pos, alice_base_key.public_key);
|
||||||
pos = olm::store_array(pos, bob_one_time_key.public_key);
|
pos = olm::store_array(pos, bob_one_time_key.public_key);
|
||||||
olm::sha256(tmp, sizeof(tmp), id);
|
_olm_crypto_sha256(tmp, sizeof(tmp), id);
|
||||||
return session_id_length();
|
return session_id_length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +323,7 @@ std::size_t olm::Session::encrypt(
|
||||||
(int)plaintext_length, plaintext);
|
(int)plaintext_length, plaintext);
|
||||||
|
|
||||||
if (message_length < encrypt_message_length(plaintext_length)) {
|
if (message_length < encrypt_message_length(plaintext_length)) {
|
||||||
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
std::uint8_t * message_body;
|
std::uint8_t * message_body;
|
||||||
|
@ -369,7 +368,7 @@ std::size_t olm::Session::encrypt(
|
||||||
|
|
||||||
if (result == std::size_t(-1)) {
|
if (result == std::size_t(-1)) {
|
||||||
last_error = ratchet.last_error;
|
last_error = ratchet.last_error;
|
||||||
ratchet.last_error = olm::ErrorCode::SUCCESS;
|
ratchet.last_error = OlmErrorCode::OLM_SUCCESS;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +392,7 @@ std::size_t olm::Session::decrypt_max_plaintext_length(
|
||||||
olm::PreKeyMessageReader reader;
|
olm::PreKeyMessageReader reader;
|
||||||
decode_one_time_key_message(reader, message, message_length);
|
decode_one_time_key_message(reader, message, message_length);
|
||||||
if (!reader.message) {
|
if (!reader.message) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
message_body = reader.message;
|
message_body = reader.message;
|
||||||
|
@ -406,7 +405,7 @@ std::size_t olm::Session::decrypt_max_plaintext_length(
|
||||||
|
|
||||||
if (result == std::size_t(-1)) {
|
if (result == std::size_t(-1)) {
|
||||||
last_error = ratchet.last_error;
|
last_error = ratchet.last_error;
|
||||||
ratchet.last_error = olm::ErrorCode::SUCCESS;
|
ratchet.last_error = OlmErrorCode::OLM_SUCCESS;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -429,7 +428,7 @@ std::size_t olm::Session::decrypt(
|
||||||
olm::PreKeyMessageReader reader;
|
olm::PreKeyMessageReader reader;
|
||||||
decode_one_time_key_message(reader, message, message_length);
|
decode_one_time_key_message(reader, message, message_length);
|
||||||
if (!reader.message) {
|
if (!reader.message) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
message_body = reader.message;
|
message_body = reader.message;
|
||||||
|
@ -442,7 +441,7 @@ std::size_t olm::Session::decrypt(
|
||||||
|
|
||||||
if (result == std::size_t(-1)) {
|
if (result == std::size_t(-1)) {
|
||||||
last_error = ratchet.last_error;
|
last_error = ratchet.last_error;
|
||||||
ratchet.last_error = olm::ErrorCode::SUCCESS;
|
ratchet.last_error = OlmErrorCode::OLM_SUCCESS;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +490,7 @@ std::uint8_t const * olm::unpickle(
|
||||||
uint32_t pickle_version;
|
uint32_t pickle_version;
|
||||||
pos = olm::unpickle(pos, end, pickle_version);
|
pos = olm::unpickle(pos, end, pickle_version);
|
||||||
if (pickle_version != SESSION_PICKLE_VERSION) {
|
if (pickle_version != SESSION_PICKLE_VERSION) {
|
||||||
value.last_error = olm::ErrorCode::UNKNOWN_PICKLE_VERSION;
|
value.last_error = OlmErrorCode::OLM_UNKNOWN_PICKLE_VERSION;
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
pos = olm::unpickle(pos, end, value.received_message);
|
pos = olm::unpickle(pos, end, value.received_message);
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
|
|
||||||
|
|
||||||
olm::Utility::Utility(
|
olm::Utility::Utility(
|
||||||
) : last_error(olm::ErrorCode::SUCCESS) {
|
) : last_error(OlmErrorCode::OLM_SUCCESS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t olm::Utility::sha256_length() {
|
size_t olm::Utility::sha256_length() {
|
||||||
return olm::SHA256_OUTPUT_LENGTH;
|
return SHA256_OUTPUT_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,11 +32,11 @@ size_t olm::Utility::sha256(
|
||||||
std::uint8_t * output, std::size_t output_length
|
std::uint8_t * output, std::size_t output_length
|
||||||
) {
|
) {
|
||||||
if (output_length < sha256_length()) {
|
if (output_length < sha256_length()) {
|
||||||
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
olm::sha256(input, input_length, output);
|
_olm_crypto_sha256(input, input_length, output);
|
||||||
return olm::SHA256_OUTPUT_LENGTH;
|
return SHA256_OUTPUT_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,11 +46,11 @@ size_t olm::Utility::ed25519_verify(
|
||||||
std::uint8_t const * signature, std::size_t signature_length
|
std::uint8_t const * signature, std::size_t signature_length
|
||||||
) {
|
) {
|
||||||
if (signature_length < olm::SIGNATURE_LENGTH) {
|
if (signature_length < olm::SIGNATURE_LENGTH) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_MAC;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
if (!olm::ed25519_verify(key, message, message_length, signature)) {
|
if (!olm::ed25519_verify(key, message, message_length, signature)) {
|
||||||
last_error = olm::ErrorCode::BAD_MESSAGE_MAC;
|
last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC;
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
return std::size_t(0);
|
return std::size_t(0);
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#include "olm/base64.hh"
|
#include "olm/base64.hh"
|
||||||
|
#include "olm/base64.h"
|
||||||
#include "unittest.hh"
|
#include "unittest.hh"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
{ /* Base64 encode test */
|
{ /* Base64 encode test */
|
||||||
TestCase test_case("Base64 encode test");
|
TestCase test_case("Base64 C++ binding encode test");
|
||||||
|
|
||||||
std::uint8_t input[] = "Hello World";
|
std::uint8_t input[] = "Hello World";
|
||||||
std::uint8_t expected_output[] = "SGVsbG8gV29ybGQ";
|
std::uint8_t expected_output[] = "SGVsbG8gV29ybGQ";
|
||||||
|
@ -18,8 +19,24 @@ olm::encode_base64(input, input_length, output);
|
||||||
assert_equals(expected_output, output, output_length);
|
assert_equals(expected_output, output, output_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TestCase test_case("Base64 C binding encode test");
|
||||||
|
|
||||||
|
std::uint8_t input[] = "Hello World";
|
||||||
|
std::uint8_t expected_output[] = "SGVsbG8gV29ybGQ";
|
||||||
|
std::size_t input_length = sizeof(input) - 1;
|
||||||
|
|
||||||
|
std::size_t output_length = ::_olm_encode_base64_length(input_length);
|
||||||
|
assert_equals(std::size_t(15), output_length);
|
||||||
|
|
||||||
|
std::uint8_t output[output_length];
|
||||||
|
output_length = ::_olm_encode_base64(input, input_length, output);
|
||||||
|
assert_equals(std::size_t(15), output_length);
|
||||||
|
assert_equals(expected_output, output, output_length);
|
||||||
|
}
|
||||||
|
|
||||||
{ /* Base64 decode test */
|
{ /* Base64 decode test */
|
||||||
TestCase test_case("Base64 decode test");
|
TestCase test_case("Base64 C++ binding decode test");
|
||||||
|
|
||||||
std::uint8_t input[] = "SGVsbG8gV29ybGQ";
|
std::uint8_t input[] = "SGVsbG8gV29ybGQ";
|
||||||
std::uint8_t expected_output[] = "Hello World";
|
std::uint8_t expected_output[] = "Hello World";
|
||||||
|
@ -33,4 +50,21 @@ olm::decode_base64(input, input_length, output);
|
||||||
assert_equals(expected_output, output, output_length);
|
assert_equals(expected_output, output, output_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TestCase test_case("Base64 C binding decode test");
|
||||||
|
|
||||||
|
std::uint8_t input[] = "SGVsbG8gV29ybGQ";
|
||||||
|
std::uint8_t expected_output[] = "Hello World";
|
||||||
|
std::size_t input_length = sizeof(input) - 1;
|
||||||
|
|
||||||
|
std::size_t output_length = ::_olm_decode_base64_length(input_length);
|
||||||
|
assert_equals(std::size_t(11), output_length);
|
||||||
|
|
||||||
|
std::uint8_t output[output_length];
|
||||||
|
output_length = ::_olm_decode_base64(input, input_length, output);
|
||||||
|
assert_equals(std::size_t(11), output_length);
|
||||||
|
assert_equals(expected_output, output, output_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@ std::uint8_t expected[32] = {
|
||||||
|
|
||||||
std::uint8_t actual[32];
|
std::uint8_t actual[32];
|
||||||
|
|
||||||
olm::sha256(input, sizeof(input), actual);
|
_olm_crypto_sha256(input, sizeof(input), actual);
|
||||||
|
|
||||||
assert_equals(expected, actual, 32);
|
assert_equals(expected, actual, 32);
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ std::uint8_t expected[32] = {
|
||||||
|
|
||||||
std::uint8_t actual[32];
|
std::uint8_t actual[32];
|
||||||
|
|
||||||
olm::hmac_sha256(input, sizeof(input), input, sizeof(input), actual);
|
_olm_crypto_hmac_sha256(input, sizeof(input), input, sizeof(input), actual);
|
||||||
|
|
||||||
assert_equals(expected, actual, 32);
|
assert_equals(expected, actual, 32);
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ std::uint8_t hmac_expected_output[32] = {
|
||||||
|
|
||||||
std::uint8_t hmac_actual_output[32] = {};
|
std::uint8_t hmac_actual_output[32] = {};
|
||||||
|
|
||||||
olm::hmac_sha256(
|
_olm_crypto_hmac_sha256(
|
||||||
salt, sizeof(salt),
|
salt, sizeof(salt),
|
||||||
input, sizeof(input),
|
input, sizeof(input),
|
||||||
hmac_actual_output
|
hmac_actual_output
|
||||||
|
@ -261,7 +261,7 @@ std::uint8_t hkdf_expected_output[42] = {
|
||||||
|
|
||||||
std::uint8_t hkdf_actual_output[42] = {};
|
std::uint8_t hkdf_actual_output[42] = {};
|
||||||
|
|
||||||
olm::hkdf_sha256(
|
_olm_crypto_hkdf_sha256(
|
||||||
input, sizeof(input),
|
input, sizeof(input),
|
||||||
salt, sizeof(salt),
|
salt, sizeof(salt),
|
||||||
info, sizeof(info),
|
info, sizeof(info),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "olm/olm.hh"
|
#include "olm/olm.h"
|
||||||
#include "unittest.hh"
|
#include "unittest.hh"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "olm/olm.hh"
|
#include "olm/olm.h"
|
||||||
#include "unittest.hh"
|
#include "unittest.hh"
|
||||||
|
|
||||||
const char * test_cases[] = {
|
const char * test_cases[] = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "olm/olm.hh"
|
#include "olm/olm.h"
|
||||||
#include "unittest.hh"
|
#include "unittest.hh"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "olm/olm.hh"
|
#include "olm/olm.h"
|
||||||
#include "unittest.hh"
|
#include "unittest.hh"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "olm/olm.hh"
|
#include "olm/olm.h"
|
||||||
#include "unittest.hh"
|
#include "unittest.hh"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "olm/ratchet.hh"
|
#include "olm/ratchet.hh"
|
||||||
#include "olm/cipher.hh"
|
#include "olm/cipher.h"
|
||||||
#include "unittest.hh"
|
#include "unittest.hh"
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,9 +28,8 @@ olm::KdfInfo kdf_info = {
|
||||||
ratchet_info, sizeof(ratchet_info) - 1
|
ratchet_info, sizeof(ratchet_info) - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
olm::CipherAesSha256 cipher(
|
_olm_cipher_aes_sha_256 cipher0 = OLM_CIPHER_INIT_AES_SHA_256(message_info);
|
||||||
message_info, sizeof(message_info) - 1
|
_olm_cipher *cipher = OLM_CIPHER_BASE(&cipher0);
|
||||||
);
|
|
||||||
|
|
||||||
std::uint8_t random_bytes[] = "0123456789ABDEF0123456789ABCDEF";
|
std::uint8_t random_bytes[] = "0123456789ABDEF0123456789ABCDEF";
|
||||||
olm::Curve25519KeyPair alice_key;
|
olm::Curve25519KeyPair alice_key;
|
||||||
|
|
Loading…
Reference in a new issue