Give SHA256 functions C bindings
This commit is contained in:
parent
4f1bb49d20
commit
e533b0dc8e
8 changed files with 100 additions and 62 deletions
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 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 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 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_ */
|
|
@ -18,6 +18,11 @@
|
|||
#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 {
|
||||
|
||||
static const std::size_t KEY_LENGTH = 32;
|
||||
|
@ -142,38 +147,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
|
||||
|
||||
#endif /* OLM_CRYPTO_HH_ */
|
||||
|
|
|
@ -36,7 +36,7 @@ static void derive_keys(
|
|||
DerivedKeys & keys
|
||||
) {
|
||||
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH + olm::IV_LENGTH];
|
||||
olm::hkdf_sha256(
|
||||
crypto_hkdf_sha256(
|
||||
key, key_length,
|
||||
nullptr, 0,
|
||||
kdf_info, kdf_info_length,
|
||||
|
@ -83,7 +83,7 @@ std::size_t olm::CipherAesSha256::encrypt(
|
|||
return std::size_t(-1);
|
||||
}
|
||||
struct 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);
|
||||
|
||||
|
@ -91,7 +91,7 @@ std::size_t olm::CipherAesSha256::encrypt(
|
|||
keys.aes_key, keys.aes_iv, plaintext, plaintext_length, ciphertext
|
||||
);
|
||||
|
||||
olm::hmac_sha256(
|
||||
crypto_hmac_sha256(
|
||||
keys.mac_key, olm::KEY_LENGTH, output, output_length - MAC_LENGTH, mac
|
||||
);
|
||||
|
||||
|
@ -115,11 +115,11 @@ std::size_t olm::CipherAesSha256::decrypt(
|
|||
std::uint8_t * plaintext, std::size_t max_plaintext_length
|
||||
) const {
|
||||
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);
|
||||
|
||||
olm::hmac_sha256(
|
||||
crypto_hmac_sha256(
|
||||
keys.mac_key, olm::KEY_LENGTH, input, input_length - MAC_LENGTH, mac
|
||||
);
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ inline static void hmac_sha256_final(
|
|||
std::uint8_t const * hmac_key,
|
||||
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);
|
||||
for (std::size_t i = 0; i < SHA256_BLOCK_LENGTH; ++i) {
|
||||
o_pad[i] ^= 0x5C;
|
||||
|
@ -255,7 +255,7 @@ std::size_t olm::aes_decrypt_cbc(
|
|||
}
|
||||
|
||||
|
||||
void olm::sha256(
|
||||
void crypto_sha256(
|
||||
std::uint8_t const * input, std::size_t input_length,
|
||||
std::uint8_t * output
|
||||
) {
|
||||
|
@ -267,7 +267,7 @@ void olm::sha256(
|
|||
}
|
||||
|
||||
|
||||
void olm::hmac_sha256(
|
||||
void crypto_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
|
||||
|
@ -283,7 +283,7 @@ void olm::hmac_sha256(
|
|||
}
|
||||
|
||||
|
||||
void olm::hkdf_sha256(
|
||||
void crypto_hkdf_sha256(
|
||||
std::uint8_t const * input, std::size_t input_length,
|
||||
std::uint8_t const * salt, std::size_t salt_length,
|
||||
std::uint8_t const * info, std::size_t info_length,
|
||||
|
@ -291,7 +291,7 @@ void olm::hkdf_sha256(
|
|||
) {
|
||||
::SHA256_CTX context;
|
||||
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::uint8_t iteration = 1;
|
||||
if (!salt) {
|
||||
|
@ -303,20 +303,20 @@ void olm::hkdf_sha256(
|
|||
hmac_sha256_init(&context, hmac_key);
|
||||
::sha256_update(&context, input, input_length);
|
||||
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 */
|
||||
hmac_sha256_init(&context, hmac_key);
|
||||
::sha256_update(&context, info, info_length);
|
||||
::sha256_update(&context, &iteration, 1);
|
||||
hmac_sha256_final(&context, hmac_key, step_result);
|
||||
while (bytes_remaining > olm::SHA256_OUTPUT_LENGTH) {
|
||||
std::memcpy(output, step_result, olm::SHA256_OUTPUT_LENGTH);
|
||||
output += olm::SHA256_OUTPUT_LENGTH;
|
||||
bytes_remaining -= olm::SHA256_OUTPUT_LENGTH;
|
||||
while (bytes_remaining > SHA256_OUTPUT_LENGTH) {
|
||||
std::memcpy(output, step_result, SHA256_OUTPUT_LENGTH);
|
||||
output += SHA256_OUTPUT_LENGTH;
|
||||
bytes_remaining -= SHA256_OUTPUT_LENGTH;
|
||||
iteration ++;
|
||||
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, &iteration, 1);
|
||||
hmac_sha256_final(&context, hmac_key, step_result);
|
||||
|
|
|
@ -50,7 +50,7 @@ static void create_chain_key(
|
|||
olm::SharedKey secret;
|
||||
olm::curve25519_shared_secret(our_key, their_key, secret);
|
||||
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
|
||||
olm::hkdf_sha256(
|
||||
crypto_hkdf_sha256(
|
||||
secret, sizeof(secret),
|
||||
root_key, sizeof(root_key),
|
||||
info.ratchet_info, info.ratchet_info_length,
|
||||
|
@ -70,7 +70,7 @@ static void advance_chain_key(
|
|||
olm::ChainKey const & chain_key,
|
||||
olm::ChainKey & new_chain_key
|
||||
) {
|
||||
olm::hmac_sha256(
|
||||
crypto_hmac_sha256(
|
||||
chain_key.key, sizeof(chain_key.key),
|
||||
CHAIN_KEY_SEED, sizeof(CHAIN_KEY_SEED),
|
||||
new_chain_key.key
|
||||
|
@ -84,7 +84,7 @@ static void create_message_keys(
|
|||
olm::ChainKey const & chain_key,
|
||||
olm::KdfInfo const & info,
|
||||
olm::MessageKey & message_key) {
|
||||
olm::hmac_sha256(
|
||||
crypto_hmac_sha256(
|
||||
chain_key.key, sizeof(chain_key.key),
|
||||
MESSAGE_KEY_SEED, sizeof(MESSAGE_KEY_SEED),
|
||||
message_key.key
|
||||
|
@ -195,7 +195,7 @@ void olm::Ratchet::initialise_as_bob(
|
|||
olm::Curve25519PublicKey const & their_ratchet_key
|
||||
) {
|
||||
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
|
||||
olm::hkdf_sha256(
|
||||
crypto_hkdf_sha256(
|
||||
shared_secret, shared_secret_length,
|
||||
nullptr, 0,
|
||||
kdf_info.root_info, kdf_info.root_info_length,
|
||||
|
@ -217,7 +217,7 @@ void olm::Ratchet::initialise_as_alice(
|
|||
olm::Curve25519KeyPair const & our_ratchet_key
|
||||
) {
|
||||
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
|
||||
olm::hkdf_sha256(
|
||||
crypto_hkdf_sha256(
|
||||
shared_secret, shared_secret_length,
|
||||
nullptr, 0,
|
||||
kdf_info.root_info, kdf_info.root_info_length,
|
||||
|
|
|
@ -192,7 +192,7 @@ std::size_t olm::Session::new_inbound_session(
|
|||
|
||||
|
||||
std::size_t olm::Session::session_id_length() {
|
||||
return olm::SHA256_OUTPUT_LENGTH;
|
||||
return SHA256_OUTPUT_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,7 +208,7 @@ std::size_t olm::Session::session_id(
|
|||
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, bob_one_time_key.public_key);
|
||||
olm::sha256(tmp, sizeof(tmp), id);
|
||||
crypto_sha256(tmp, sizeof(tmp), id);
|
||||
return session_id_length();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ olm::Utility::Utility(
|
|||
|
||||
|
||||
size_t olm::Utility::sha256_length() {
|
||||
return olm::SHA256_OUTPUT_LENGTH;
|
||||
return SHA256_OUTPUT_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,8 +35,8 @@ size_t olm::Utility::sha256(
|
|||
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
||||
return std::size_t(-1);
|
||||
}
|
||||
olm::sha256(input, input_length, output);
|
||||
return olm::SHA256_OUTPUT_LENGTH;
|
||||
crypto_sha256(input, input_length, output);
|
||||
return SHA256_OUTPUT_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ std::uint8_t expected[32] = {
|
|||
|
||||
std::uint8_t actual[32];
|
||||
|
||||
olm::sha256(input, sizeof(input), actual);
|
||||
crypto_sha256(input, sizeof(input), actual);
|
||||
|
||||
assert_equals(expected, actual, 32);
|
||||
|
||||
|
@ -207,7 +207,7 @@ std::uint8_t expected[32] = {
|
|||
|
||||
std::uint8_t actual[32];
|
||||
|
||||
olm::hmac_sha256(input, sizeof(input), input, sizeof(input), actual);
|
||||
crypto_hmac_sha256(input, sizeof(input), input, sizeof(input), actual);
|
||||
|
||||
assert_equals(expected, actual, 32);
|
||||
|
||||
|
@ -242,7 +242,7 @@ std::uint8_t hmac_expected_output[32] = {
|
|||
|
||||
std::uint8_t hmac_actual_output[32] = {};
|
||||
|
||||
olm::hmac_sha256(
|
||||
crypto_hmac_sha256(
|
||||
salt, sizeof(salt),
|
||||
input, sizeof(input),
|
||||
hmac_actual_output
|
||||
|
@ -261,7 +261,7 @@ std::uint8_t hkdf_expected_output[42] = {
|
|||
|
||||
std::uint8_t hkdf_actual_output[42] = {};
|
||||
|
||||
olm::hkdf_sha256(
|
||||
crypto_hkdf_sha256(
|
||||
input, sizeof(input),
|
||||
salt, sizeof(salt),
|
||||
info, sizeof(info),
|
||||
|
|
Loading…
Reference in a new issue