Convert AES functions to plain C
This commit is contained in:
parent
f0acf6582f
commit
69f269ffaf
10 changed files with 68 additions and 100 deletions
|
@ -16,7 +16,7 @@
|
||||||
#define OLM_ACCOUNT_HH_
|
#define OLM_ACCOUNT_HH_
|
||||||
|
|
||||||
#include "olm/list.hh"
|
#include "olm/list.hh"
|
||||||
#include "olm/crypto.hh"
|
#include "olm/crypto.h"
|
||||||
#include "olm/error.h"
|
#include "olm/error.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
|
@ -57,6 +57,15 @@ extern "C" {
|
||||||
/** length of an aes256 initialisation vector */
|
/** length of an aes256 initialisation vector */
|
||||||
#define AES256_IV_LENGTH 16
|
#define AES256_IV_LENGTH 16
|
||||||
|
|
||||||
|
struct _olm_aes256_key {
|
||||||
|
uint8_t key[AES256_KEY_LENGTH];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _olm_aes256_iv {
|
||||||
|
uint8_t iv[AES256_IV_LENGTH];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct _olm_curve25519_public_key {
|
struct _olm_curve25519_public_key {
|
||||||
uint8_t public_key[CURVE25519_KEY_LENGTH];
|
uint8_t public_key[CURVE25519_KEY_LENGTH];
|
||||||
};
|
};
|
||||||
|
@ -84,6 +93,32 @@ struct _olm_ed25519_key_pair {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** The length of output the aes_encrypt_cbc function will write */
|
||||||
|
size_t _olm_crypto_aes_encrypt_cbc_length(
|
||||||
|
size_t input_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Encrypts the input using AES256 in CBC mode with PKCS#7 padding.
|
||||||
|
* The output buffer must be big enough to hold the output including padding */
|
||||||
|
void _olm_crypto_aes_encrypt_cbc(
|
||||||
|
const struct _olm_aes256_key *key,
|
||||||
|
const struct _olm_aes256_iv *iv,
|
||||||
|
const uint8_t *input, size_t input_length,
|
||||||
|
uint8_t *output
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Decrypts the input using AES256 in CBC mode. The output buffer must be at
|
||||||
|
* least the same size as the input buffer. Returns the length of the plaintext
|
||||||
|
* without padding on success or std::size_t(-1) if the padding is invalid.
|
||||||
|
*/
|
||||||
|
size_t _olm_crypto_aes_decrypt_cbc(
|
||||||
|
const struct _olm_aes256_key *key,
|
||||||
|
const struct _olm_aes256_iv *iv,
|
||||||
|
uint8_t const * input, size_t input_length,
|
||||||
|
uint8_t * output
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/** Computes SHA-256 of the input. The output buffer must be a least
|
/** Computes SHA-256 of the input. The output buffer must be a least
|
||||||
* SHA256_OUTPUT_LENGTH (32) bytes long. */
|
* SHA256_OUTPUT_LENGTH (32) bytes long. */
|
||||||
void _olm_crypto_sha256(
|
void _olm_crypto_sha256(
|
||||||
|
|
|
@ -1,69 +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_CRYPTO_HH_
|
|
||||||
#define OLM_CRYPTO_HH_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
// 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 {
|
|
||||||
|
|
||||||
|
|
||||||
struct Aes256Key {
|
|
||||||
std::uint8_t key[AES256_KEY_LENGTH];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Aes256Iv {
|
|
||||||
std::uint8_t iv[AES256_IV_LENGTH];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** The length of output the aes_encrypt_cbc function will write */
|
|
||||||
std::size_t aes_encrypt_cbc_length(
|
|
||||||
std::size_t input_length
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/** Encrypts the input using AES256 in CBC mode with PKCS#7 padding.
|
|
||||||
* The output buffer must be big enough to hold the output including padding */
|
|
||||||
void aes_encrypt_cbc(
|
|
||||||
Aes256Key const & key,
|
|
||||||
Aes256Iv const & iv,
|
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
|
||||||
std::uint8_t * output
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/** Decrypts the input using AES256 in CBC mode. The output buffer must be at
|
|
||||||
* least the same size as the input buffer. Returns the length of the plaintext
|
|
||||||
* without padding on success or std::size_t(-1) if the padding is invalid.
|
|
||||||
*/
|
|
||||||
std::size_t aes_decrypt_cbc(
|
|
||||||
Aes256Key const & key,
|
|
||||||
Aes256Iv const & iv,
|
|
||||||
std::uint8_t const * input, std::size_t input_length,
|
|
||||||
std::uint8_t * output
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace olm
|
|
||||||
|
|
||||||
#endif /* OLM_CRYPTO_HH_ */
|
|
|
@ -16,7 +16,7 @@
|
||||||
#define OLM_PICKLE_HH_
|
#define OLM_PICKLE_HH_
|
||||||
|
|
||||||
#include "olm/list.hh"
|
#include "olm/list.hh"
|
||||||
#include "olm/crypto.hh"
|
#include "olm/crypto.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "olm/crypto.hh"
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "olm/crypto.h"
|
||||||
#include "olm/list.hh"
|
#include "olm/list.hh"
|
||||||
#include "olm/error.h"
|
#include "olm/error.h"
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "olm/cipher.h"
|
#include "olm/cipher.h"
|
||||||
#include "olm/crypto.hh"
|
#include "olm/crypto.h"
|
||||||
#include "olm/memory.hh"
|
#include "olm/memory.hh"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ const std::size_t HMAC_KEY_LENGTH = 32;
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct DerivedKeys {
|
struct DerivedKeys {
|
||||||
olm::Aes256Key aes_key;
|
_olm_aes256_key aes_key;
|
||||||
std::uint8_t mac_key[HMAC_KEY_LENGTH];
|
std::uint8_t mac_key[HMAC_KEY_LENGTH];
|
||||||
olm::Aes256Iv aes_iv;
|
_olm_aes256_iv aes_iv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ size_t aes_sha_256_cipher_mac_length(const struct _olm_cipher *cipher) {
|
||||||
size_t aes_sha_256_cipher_encrypt_ciphertext_length(
|
size_t aes_sha_256_cipher_encrypt_ciphertext_length(
|
||||||
const struct _olm_cipher *cipher, size_t plaintext_length
|
const struct _olm_cipher *cipher, size_t plaintext_length
|
||||||
) {
|
) {
|
||||||
return olm::aes_encrypt_cbc_length(plaintext_length);
|
return _olm_crypto_aes_encrypt_cbc_length(plaintext_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t aes_sha_256_cipher_encrypt(
|
size_t aes_sha_256_cipher_encrypt(
|
||||||
|
@ -80,8 +80,8 @@ size_t aes_sha_256_cipher_encrypt(
|
||||||
|
|
||||||
derive_keys(c->kdf_info, c->kdf_info_length, key, key_length, keys);
|
derive_keys(c->kdf_info, c->kdf_info_length, key, key_length, keys);
|
||||||
|
|
||||||
olm::aes_encrypt_cbc(
|
_olm_crypto_aes_encrypt_cbc(
|
||||||
keys.aes_key, keys.aes_iv, plaintext, plaintext_length, ciphertext
|
&keys.aes_key, &keys.aes_iv, plaintext, plaintext_length, ciphertext
|
||||||
);
|
);
|
||||||
|
|
||||||
_olm_crypto_hmac_sha256(
|
_olm_crypto_hmac_sha256(
|
||||||
|
@ -126,8 +126,8 @@ size_t aes_sha_256_cipher_decrypt(
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t plaintext_length = olm::aes_decrypt_cbc(
|
std::size_t plaintext_length = _olm_crypto_aes_decrypt_cbc(
|
||||||
keys.aes_key, keys.aes_iv, ciphertext, ciphertext_length, plaintext
|
&keys.aes_key, &keys.aes_iv, ciphertext, ciphertext_length, plaintext
|
||||||
);
|
);
|
||||||
|
|
||||||
olm::unset(keys);
|
olm::unset(keys);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* 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/crypto.hh"
|
#include "olm/crypto.h"
|
||||||
#include "olm/memory.hh"
|
#include "olm/memory.hh"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -163,23 +163,23 @@ int _olm_crypto_ed25519_verify(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::size_t olm::aes_encrypt_cbc_length(
|
std::size_t _olm_crypto_aes_encrypt_cbc_length(
|
||||||
std::size_t input_length
|
std::size_t input_length
|
||||||
) {
|
) {
|
||||||
return input_length + AES_BLOCK_LENGTH - input_length % AES_BLOCK_LENGTH;
|
return input_length + AES_BLOCK_LENGTH - input_length % AES_BLOCK_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void olm::aes_encrypt_cbc(
|
void _olm_crypto_aes_encrypt_cbc(
|
||||||
olm::Aes256Key const & key,
|
_olm_aes256_key const *key,
|
||||||
olm::Aes256Iv const & iv,
|
_olm_aes256_iv const *iv,
|
||||||
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
|
||||||
) {
|
) {
|
||||||
std::uint32_t key_schedule[AES_KEY_SCHEDULE_LENGTH];
|
std::uint32_t key_schedule[AES_KEY_SCHEDULE_LENGTH];
|
||||||
::aes_key_setup(key.key, key_schedule, AES_KEY_BITS);
|
::aes_key_setup(key->key, key_schedule, AES_KEY_BITS);
|
||||||
std::uint8_t input_block[AES_BLOCK_LENGTH];
|
std::uint8_t input_block[AES_BLOCK_LENGTH];
|
||||||
std::memcpy(input_block, iv.iv, AES_BLOCK_LENGTH);
|
std::memcpy(input_block, iv->iv, AES_BLOCK_LENGTH);
|
||||||
while (input_length >= AES_BLOCK_LENGTH) {
|
while (input_length >= AES_BLOCK_LENGTH) {
|
||||||
xor_block<AES_BLOCK_LENGTH>(input_block, input);
|
xor_block<AES_BLOCK_LENGTH>(input_block, input);
|
||||||
::aes_encrypt(input_block, output, key_schedule, AES_KEY_BITS);
|
::aes_encrypt(input_block, output, key_schedule, AES_KEY_BITS);
|
||||||
|
@ -201,17 +201,17 @@ void olm::aes_encrypt_cbc(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::size_t olm::aes_decrypt_cbc(
|
std::size_t _olm_crypto_aes_decrypt_cbc(
|
||||||
olm::Aes256Key const & key,
|
_olm_aes256_key const *key,
|
||||||
olm::Aes256Iv const & iv,
|
_olm_aes256_iv const *iv,
|
||||||
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
|
||||||
) {
|
) {
|
||||||
std::uint32_t key_schedule[AES_KEY_SCHEDULE_LENGTH];
|
std::uint32_t key_schedule[AES_KEY_SCHEDULE_LENGTH];
|
||||||
::aes_key_setup(key.key, key_schedule, AES_KEY_BITS);
|
::aes_key_setup(key->key, key_schedule, AES_KEY_BITS);
|
||||||
std::uint8_t block1[AES_BLOCK_LENGTH];
|
std::uint8_t block1[AES_BLOCK_LENGTH];
|
||||||
std::uint8_t block2[AES_BLOCK_LENGTH];
|
std::uint8_t block2[AES_BLOCK_LENGTH];
|
||||||
std::memcpy(block1, iv.iv, AES_BLOCK_LENGTH);
|
std::memcpy(block1, iv->iv, AES_BLOCK_LENGTH);
|
||||||
for (std::size_t i = 0; i < input_length; i += AES_BLOCK_LENGTH) {
|
for (std::size_t i = 0; i < input_length; i += AES_BLOCK_LENGTH) {
|
||||||
std::memcpy(block2, &input[i], AES_BLOCK_LENGTH);
|
std::memcpy(block2, &input[i], AES_BLOCK_LENGTH);
|
||||||
::aes_decrypt(&input[i], &output[i], key_schedule, AES_KEY_BITS);
|
::aes_decrypt(&input[i], &output[i], key_schedule, AES_KEY_BITS);
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
*/
|
*/
|
||||||
#include "olm/session.hh"
|
#include "olm/session.hh"
|
||||||
#include "olm/cipher.h"
|
#include "olm/cipher.h"
|
||||||
#include "olm/crypto.hh"
|
#include "olm/crypto.h"
|
||||||
#include "olm/account.hh"
|
#include "olm/account.hh"
|
||||||
#include "olm/memory.hh"
|
#include "olm/memory.hh"
|
||||||
#include "olm/message.hh"
|
#include "olm/message.hh"
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "olm/utility.hh"
|
#include "olm/utility.hh"
|
||||||
#include "olm/crypto.hh"
|
#include "olm/crypto.h"
|
||||||
|
|
||||||
|
|
||||||
olm::Utility::Utility(
|
olm::Utility::Utility(
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* 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/crypto.hh"
|
#include "olm/crypto.h"
|
||||||
|
|
||||||
#include "unittest.hh"
|
#include "unittest.hh"
|
||||||
|
|
||||||
|
@ -115,8 +115,8 @@ assert_equals(false, result);
|
||||||
|
|
||||||
TestCase test_case("AES Test Case 1");
|
TestCase test_case("AES Test Case 1");
|
||||||
|
|
||||||
olm::Aes256Key key = {};
|
_olm_aes256_key key = {};
|
||||||
olm::Aes256Iv iv = {};
|
_olm_aes256_iv iv = {};
|
||||||
std::uint8_t input[16] = {};
|
std::uint8_t input[16] = {};
|
||||||
|
|
||||||
std::uint8_t expected[32] = {
|
std::uint8_t expected[32] = {
|
||||||
|
@ -126,16 +126,16 @@ std::uint8_t expected[32] = {
|
||||||
0x4B, 0xAE, 0xDF, 0xFC, 0x3D, 0x21, 0x4C, 0x38
|
0x4B, 0xAE, 0xDF, 0xFC, 0x3D, 0x21, 0x4C, 0x38
|
||||||
};
|
};
|
||||||
|
|
||||||
std::size_t length = olm::aes_encrypt_cbc_length(sizeof(input));
|
std::size_t length = _olm_crypto_aes_encrypt_cbc_length(sizeof(input));
|
||||||
assert_equals(std::size_t(32), length);
|
assert_equals(std::size_t(32), length);
|
||||||
|
|
||||||
|
|
||||||
std::uint8_t actual[32] = {};
|
std::uint8_t actual[32] = {};
|
||||||
|
|
||||||
olm::aes_encrypt_cbc(key, iv, input, sizeof(input), actual);
|
_olm_crypto_aes_encrypt_cbc(&key, &iv, input, sizeof(input), actual);
|
||||||
assert_equals(expected, actual, 32);
|
assert_equals(expected, actual, 32);
|
||||||
|
|
||||||
length = olm::aes_decrypt_cbc(key, iv, expected, sizeof(expected), actual);
|
length = _olm_crypto_aes_decrypt_cbc(&key, &iv, expected, sizeof(expected), actual);
|
||||||
assert_equals(std::size_t(16), length);
|
assert_equals(std::size_t(16), length);
|
||||||
assert_equals(input, actual, length);
|
assert_equals(input, actual, length);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue