diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2017-02-13 07:56:33 +0300 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2017-02-13 09:09:08 +0300 |
commit | 193f645f65ad4ffdec3186e4176b23af10861199 (patch) | |
tree | e1b16b48ac74c5f03f99a98798e849f6dd9752cc /libs/libaxolotl/src | |
parent | 36c32a13878d3bd94e88bd9c764f1eadb05ea1ed (diff) |
libs:
libaxolotl:
updated libaxolotl (libsignal-c) from (https://github.com/WhisperSystems/libsignal-protocol-c)
Diffstat (limited to 'libs/libaxolotl/src')
90 files changed, 6113 insertions, 3593 deletions
diff --git a/libs/libaxolotl/src/CMakeLists.txt b/libs/libaxolotl/src/CMakeLists.txt index 3900713add..54a24d0a6c 100644 --- a/libs/libaxolotl/src/CMakeLists.txt +++ b/libs/libaxolotl/src/CMakeLists.txt @@ -13,13 +13,13 @@ set(protobuf_SRCS FingerprintProtocol.pb-c.c ) -set(axolotl_SRCS +set(signal_protocol_SRCS vpool.c vpool.h - axolotl.c - axolotl.h - axolotl_types.h - axolotl_internal.h + signal_protocol.c + signal_protocol.h + signal_protocol_types.h + signal_protocol_internal.h curve.c curve.h hkdf.c @@ -36,6 +36,7 @@ set(axolotl_SRCS session_pre_key.h session_builder.c session_builder.h + session_builder_internal.h session_cipher.c session_cipher.h key_helper.c @@ -52,22 +53,24 @@ set(axolotl_SRCS group_cipher.h fingerprint.c fingerprint.h + device_consistency.c + device_consistency.h ) add_subdirectory(curve25519) add_subdirectory(protobuf-c) -add_library(axolotl-c +add_library(signal-protocol-c ${protobuf_SRCS} - ${axolotl_SRCS} + ${signal_protocol_SRCS} $<TARGET_OBJECTS:curve25519> $<TARGET_OBJECTS:protobuf-c> ) INSTALL( FILES - axolotl.h - axolotl_types.h + signal_protocol.h + signal_protocol_types.h curve.h hkdf.h ratchet.h @@ -84,7 +87,8 @@ INSTALL( group_session_builder.h group_cipher.h fingerprint.h - DESTINATION include/axolotl + device_consistency.h + DESTINATION ${INCLUDE_INSTALL_DIR}/signal ) -INSTALL(TARGETS axolotl-c DESTINATION lib) +INSTALL(TARGETS signal-protocol-c DESTINATION ${LIB_INSTALL_DIR}) diff --git a/libs/libaxolotl/src/FingerprintProtocol.pb-c.h b/libs/libaxolotl/src/FingerprintProtocol.pb-c.h index 8bfce6eaeb..8bfce6eaeb 100644..100755 --- a/libs/libaxolotl/src/FingerprintProtocol.pb-c.h +++ b/libs/libaxolotl/src/FingerprintProtocol.pb-c.h diff --git a/libs/libaxolotl/src/LocalStorageProtocol.pb-c.h b/libs/libaxolotl/src/LocalStorageProtocol.pb-c.h index 86e657e51a..86e657e51a 100644..100755 --- a/libs/libaxolotl/src/LocalStorageProtocol.pb-c.h +++ b/libs/libaxolotl/src/LocalStorageProtocol.pb-c.h diff --git a/libs/libaxolotl/src/WhisperTextProtocol.pb-c.c b/libs/libaxolotl/src/WhisperTextProtocol.pb-c.c index 12c756a047..f73c0642fe 100644 --- a/libs/libaxolotl/src/WhisperTextProtocol.pb-c.c +++ b/libs/libaxolotl/src/WhisperTextProtocol.pb-c.c @@ -7,90 +7,90 @@ #endif #include "WhisperTextProtocol.pb-c.h" -void textsecure__whisper_message__init - (Textsecure__WhisperMessage *message) +void textsecure__signal_message__init + (Textsecure__SignalMessage *message) { - static Textsecure__WhisperMessage init_value = TEXTSECURE__WHISPER_MESSAGE__INIT; + static Textsecure__SignalMessage init_value = TEXTSECURE__SIGNAL_MESSAGE__INIT; *message = init_value; } -size_t textsecure__whisper_message__get_packed_size - (const Textsecure__WhisperMessage *message) +size_t textsecure__signal_message__get_packed_size + (const Textsecure__SignalMessage *message) { - assert(message->base.descriptor == &textsecure__whisper_message__descriptor); + assert(message->base.descriptor == &textsecure__signal_message__descriptor); return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); } -size_t textsecure__whisper_message__pack - (const Textsecure__WhisperMessage *message, +size_t textsecure__signal_message__pack + (const Textsecure__SignalMessage *message, uint8_t *out) { - assert(message->base.descriptor == &textsecure__whisper_message__descriptor); + assert(message->base.descriptor == &textsecure__signal_message__descriptor); return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); } -size_t textsecure__whisper_message__pack_to_buffer - (const Textsecure__WhisperMessage *message, +size_t textsecure__signal_message__pack_to_buffer + (const Textsecure__SignalMessage *message, ProtobufCBuffer *buffer) { - assert(message->base.descriptor == &textsecure__whisper_message__descriptor); + assert(message->base.descriptor == &textsecure__signal_message__descriptor); return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); } -Textsecure__WhisperMessage * - textsecure__whisper_message__unpack +Textsecure__SignalMessage * + textsecure__signal_message__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { - return (Textsecure__WhisperMessage *) - protobuf_c_message_unpack (&textsecure__whisper_message__descriptor, + return (Textsecure__SignalMessage *) + protobuf_c_message_unpack (&textsecure__signal_message__descriptor, allocator, len, data); } -void textsecure__whisper_message__free_unpacked - (Textsecure__WhisperMessage *message, +void textsecure__signal_message__free_unpacked + (Textsecure__SignalMessage *message, ProtobufCAllocator *allocator) { - assert(message->base.descriptor == &textsecure__whisper_message__descriptor); + assert(message->base.descriptor == &textsecure__signal_message__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -void textsecure__pre_key_whisper_message__init - (Textsecure__PreKeyWhisperMessage *message) +void textsecure__pre_key_signal_message__init + (Textsecure__PreKeySignalMessage *message) { - static Textsecure__PreKeyWhisperMessage init_value = TEXTSECURE__PRE_KEY_WHISPER_MESSAGE__INIT; + static Textsecure__PreKeySignalMessage init_value = TEXTSECURE__PRE_KEY_SIGNAL_MESSAGE__INIT; *message = init_value; } -size_t textsecure__pre_key_whisper_message__get_packed_size - (const Textsecure__PreKeyWhisperMessage *message) +size_t textsecure__pre_key_signal_message__get_packed_size + (const Textsecure__PreKeySignalMessage *message) { - assert(message->base.descriptor == &textsecure__pre_key_whisper_message__descriptor); + assert(message->base.descriptor == &textsecure__pre_key_signal_message__descriptor); return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); } -size_t textsecure__pre_key_whisper_message__pack - (const Textsecure__PreKeyWhisperMessage *message, +size_t textsecure__pre_key_signal_message__pack + (const Textsecure__PreKeySignalMessage *message, uint8_t *out) { - assert(message->base.descriptor == &textsecure__pre_key_whisper_message__descriptor); + assert(message->base.descriptor == &textsecure__pre_key_signal_message__descriptor); return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); } -size_t textsecure__pre_key_whisper_message__pack_to_buffer - (const Textsecure__PreKeyWhisperMessage *message, +size_t textsecure__pre_key_signal_message__pack_to_buffer + (const Textsecure__PreKeySignalMessage *message, ProtobufCBuffer *buffer) { - assert(message->base.descriptor == &textsecure__pre_key_whisper_message__descriptor); + assert(message->base.descriptor == &textsecure__pre_key_signal_message__descriptor); return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); } -Textsecure__PreKeyWhisperMessage * - textsecure__pre_key_whisper_message__unpack +Textsecure__PreKeySignalMessage * + textsecure__pre_key_signal_message__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { - return (Textsecure__PreKeyWhisperMessage *) - protobuf_c_message_unpack (&textsecure__pre_key_whisper_message__descriptor, + return (Textsecure__PreKeySignalMessage *) + protobuf_c_message_unpack (&textsecure__pre_key_signal_message__descriptor, allocator, len, data); } -void textsecure__pre_key_whisper_message__free_unpacked - (Textsecure__PreKeyWhisperMessage *message, +void textsecure__pre_key_signal_message__free_unpacked + (Textsecure__PreKeySignalMessage *message, ProtobufCAllocator *allocator) { - assert(message->base.descriptor == &textsecure__pre_key_whisper_message__descriptor); + assert(message->base.descriptor == &textsecure__pre_key_signal_message__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } void textsecure__key_exchange_message__init @@ -222,15 +222,58 @@ void textsecure__sender_key_distribution_message__free_unpacked assert(message->base.descriptor == &textsecure__sender_key_distribution_message__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -static const ProtobufCFieldDescriptor textsecure__whisper_message__field_descriptors[4] = +void textsecure__device_consistency_code_message__init + (Textsecure__DeviceConsistencyCodeMessage *message) +{ + static Textsecure__DeviceConsistencyCodeMessage init_value = TEXTSECURE__DEVICE_CONSISTENCY_CODE_MESSAGE__INIT; + *message = init_value; +} +size_t textsecure__device_consistency_code_message__get_packed_size + (const Textsecure__DeviceConsistencyCodeMessage *message) +{ + assert(message->base.descriptor == &textsecure__device_consistency_code_message__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t textsecure__device_consistency_code_message__pack + (const Textsecure__DeviceConsistencyCodeMessage *message, + uint8_t *out) +{ + assert(message->base.descriptor == &textsecure__device_consistency_code_message__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t textsecure__device_consistency_code_message__pack_to_buffer + (const Textsecure__DeviceConsistencyCodeMessage *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &textsecure__device_consistency_code_message__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Textsecure__DeviceConsistencyCodeMessage * + textsecure__device_consistency_code_message__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Textsecure__DeviceConsistencyCodeMessage *) + protobuf_c_message_unpack (&textsecure__device_consistency_code_message__descriptor, + allocator, len, data); +} +void textsecure__device_consistency_code_message__free_unpacked + (Textsecure__DeviceConsistencyCodeMessage *message, + ProtobufCAllocator *allocator) +{ + assert(message->base.descriptor == &textsecure__device_consistency_code_message__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor textsecure__signal_message__field_descriptors[4] = { { "ratchetKey", 1, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BYTES, - offsetof(Textsecure__WhisperMessage, has_ratchetkey), - offsetof(Textsecure__WhisperMessage, ratchetkey), + offsetof(Textsecure__SignalMessage, has_ratchetkey), + offsetof(Textsecure__SignalMessage, ratchetkey), NULL, NULL, 0, /* flags */ @@ -241,8 +284,8 @@ static const ProtobufCFieldDescriptor textsecure__whisper_message__field_descrip 2, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_UINT32, - offsetof(Textsecure__WhisperMessage, has_counter), - offsetof(Textsecure__WhisperMessage, counter), + offsetof(Textsecure__SignalMessage, has_counter), + offsetof(Textsecure__SignalMessage, counter), NULL, NULL, 0, /* flags */ @@ -253,8 +296,8 @@ static const ProtobufCFieldDescriptor textsecure__whisper_message__field_descrip 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_UINT32, - offsetof(Textsecure__WhisperMessage, has_previouscounter), - offsetof(Textsecure__WhisperMessage, previouscounter), + offsetof(Textsecure__SignalMessage, has_previouscounter), + offsetof(Textsecure__SignalMessage, previouscounter), NULL, NULL, 0, /* flags */ @@ -265,49 +308,49 @@ static const ProtobufCFieldDescriptor textsecure__whisper_message__field_descrip 4, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BYTES, - offsetof(Textsecure__WhisperMessage, has_ciphertext), - offsetof(Textsecure__WhisperMessage, ciphertext), + offsetof(Textsecure__SignalMessage, has_ciphertext), + offsetof(Textsecure__SignalMessage, ciphertext), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; -static const unsigned textsecure__whisper_message__field_indices_by_name[] = { +static const unsigned textsecure__signal_message__field_indices_by_name[] = { 3, /* field[3] = ciphertext */ 1, /* field[1] = counter */ 2, /* field[2] = previousCounter */ 0, /* field[0] = ratchetKey */ }; -static const ProtobufCIntRange textsecure__whisper_message__number_ranges[1 + 1] = +static const ProtobufCIntRange textsecure__signal_message__number_ranges[1 + 1] = { { 1, 0 }, { 0, 4 } }; -const ProtobufCMessageDescriptor textsecure__whisper_message__descriptor = +const ProtobufCMessageDescriptor textsecure__signal_message__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "textsecure.WhisperMessage", - "WhisperMessage", - "Textsecure__WhisperMessage", + "textsecure.SignalMessage", + "SignalMessage", + "Textsecure__SignalMessage", "textsecure", - sizeof(Textsecure__WhisperMessage), + sizeof(Textsecure__SignalMessage), 4, - textsecure__whisper_message__field_descriptors, - textsecure__whisper_message__field_indices_by_name, - 1, textsecure__whisper_message__number_ranges, - (ProtobufCMessageInit) textsecure__whisper_message__init, + textsecure__signal_message__field_descriptors, + textsecure__signal_message__field_indices_by_name, + 1, textsecure__signal_message__number_ranges, + (ProtobufCMessageInit) textsecure__signal_message__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor textsecure__pre_key_whisper_message__field_descriptors[6] = +static const ProtobufCFieldDescriptor textsecure__pre_key_signal_message__field_descriptors[6] = { { "preKeyId", 1, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_UINT32, - offsetof(Textsecure__PreKeyWhisperMessage, has_prekeyid), - offsetof(Textsecure__PreKeyWhisperMessage, prekeyid), + offsetof(Textsecure__PreKeySignalMessage, has_prekeyid), + offsetof(Textsecure__PreKeySignalMessage, prekeyid), NULL, NULL, 0, /* flags */ @@ -318,8 +361,8 @@ static const ProtobufCFieldDescriptor textsecure__pre_key_whisper_message__field 2, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BYTES, - offsetof(Textsecure__PreKeyWhisperMessage, has_basekey), - offsetof(Textsecure__PreKeyWhisperMessage, basekey), + offsetof(Textsecure__PreKeySignalMessage, has_basekey), + offsetof(Textsecure__PreKeySignalMessage, basekey), NULL, NULL, 0, /* flags */ @@ -330,8 +373,8 @@ static const ProtobufCFieldDescriptor textsecure__pre_key_whisper_message__field 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BYTES, - offsetof(Textsecure__PreKeyWhisperMessage, has_identitykey), - offsetof(Textsecure__PreKeyWhisperMessage, identitykey), + offsetof(Textsecure__PreKeySignalMessage, has_identitykey), + offsetof(Textsecure__PreKeySignalMessage, identitykey), NULL, NULL, 0, /* flags */ @@ -342,8 +385,8 @@ static const ProtobufCFieldDescriptor textsecure__pre_key_whisper_message__field 4, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BYTES, - offsetof(Textsecure__PreKeyWhisperMessage, has_message), - offsetof(Textsecure__PreKeyWhisperMessage, message), + offsetof(Textsecure__PreKeySignalMessage, has_message), + offsetof(Textsecure__PreKeySignalMessage, message), NULL, NULL, 0, /* flags */ @@ -354,8 +397,8 @@ static const ProtobufCFieldDescriptor textsecure__pre_key_whisper_message__field 5, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_UINT32, - offsetof(Textsecure__PreKeyWhisperMessage, has_registrationid), - offsetof(Textsecure__PreKeyWhisperMessage, registrationid), + offsetof(Textsecure__PreKeySignalMessage, has_registrationid), + offsetof(Textsecure__PreKeySignalMessage, registrationid), NULL, NULL, 0, /* flags */ @@ -366,15 +409,15 @@ static const ProtobufCFieldDescriptor textsecure__pre_key_whisper_message__field 6, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_UINT32, - offsetof(Textsecure__PreKeyWhisperMessage, has_signedprekeyid), - offsetof(Textsecure__PreKeyWhisperMessage, signedprekeyid), + offsetof(Textsecure__PreKeySignalMessage, has_signedprekeyid), + offsetof(Textsecure__PreKeySignalMessage, signedprekeyid), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; -static const unsigned textsecure__pre_key_whisper_message__field_indices_by_name[] = { +static const unsigned textsecure__pre_key_signal_message__field_indices_by_name[] = { 1, /* field[1] = baseKey */ 2, /* field[2] = identityKey */ 3, /* field[3] = message */ @@ -382,24 +425,24 @@ static const unsigned textsecure__pre_key_whisper_message__field_indices_by_name 4, /* field[4] = registrationId */ 5, /* field[5] = signedPreKeyId */ }; -static const ProtobufCIntRange textsecure__pre_key_whisper_message__number_ranges[1 + 1] = +static const ProtobufCIntRange textsecure__pre_key_signal_message__number_ranges[1 + 1] = { { 1, 0 }, { 0, 6 } }; -const ProtobufCMessageDescriptor textsecure__pre_key_whisper_message__descriptor = +const ProtobufCMessageDescriptor textsecure__pre_key_signal_message__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "textsecure.PreKeyWhisperMessage", - "PreKeyWhisperMessage", - "Textsecure__PreKeyWhisperMessage", + "textsecure.PreKeySignalMessage", + "PreKeySignalMessage", + "Textsecure__PreKeySignalMessage", "textsecure", - sizeof(Textsecure__PreKeyWhisperMessage), + sizeof(Textsecure__PreKeySignalMessage), 6, - textsecure__pre_key_whisper_message__field_descriptors, - textsecure__pre_key_whisper_message__field_indices_by_name, - 1, textsecure__pre_key_whisper_message__number_ranges, - (ProtobufCMessageInit) textsecure__pre_key_whisper_message__init, + textsecure__pre_key_signal_message__field_descriptors, + textsecure__pre_key_signal_message__field_indices_by_name, + 1, textsecure__pre_key_signal_message__number_ranges, + (ProtobufCMessageInit) textsecure__pre_key_signal_message__init, NULL,NULL,NULL /* reserved[123] */ }; static const ProtobufCFieldDescriptor textsecure__key_exchange_message__field_descriptors[5] = @@ -633,3 +676,54 @@ const ProtobufCMessageDescriptor textsecure__sender_key_distribution_message__de (ProtobufCMessageInit) textsecure__sender_key_distribution_message__init, NULL,NULL,NULL /* reserved[123] */ }; +static const ProtobufCFieldDescriptor textsecure__device_consistency_code_message__field_descriptors[2] = +{ + { + "generation", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_UINT32, + offsetof(Textsecure__DeviceConsistencyCodeMessage, has_generation), + offsetof(Textsecure__DeviceConsistencyCodeMessage, generation), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "signature", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(Textsecure__DeviceConsistencyCodeMessage, has_signature), + offsetof(Textsecure__DeviceConsistencyCodeMessage, signature), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned textsecure__device_consistency_code_message__field_indices_by_name[] = { + 0, /* field[0] = generation */ + 1, /* field[1] = signature */ +}; +static const ProtobufCIntRange textsecure__device_consistency_code_message__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor textsecure__device_consistency_code_message__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "textsecure.DeviceConsistencyCodeMessage", + "DeviceConsistencyCodeMessage", + "Textsecure__DeviceConsistencyCodeMessage", + "textsecure", + sizeof(Textsecure__DeviceConsistencyCodeMessage), + 2, + textsecure__device_consistency_code_message__field_descriptors, + textsecure__device_consistency_code_message__field_indices_by_name, + 1, textsecure__device_consistency_code_message__number_ranges, + (ProtobufCMessageInit) textsecure__device_consistency_code_message__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/libs/libaxolotl/src/WhisperTextProtocol.pb-c.h b/libs/libaxolotl/src/WhisperTextProtocol.pb-c.h index 909a7f59f3..de589106bb 100644..100755 --- a/libs/libaxolotl/src/WhisperTextProtocol.pb-c.h +++ b/libs/libaxolotl/src/WhisperTextProtocol.pb-c.h @@ -15,11 +15,12 @@ PROTOBUF_C__BEGIN_DECLS #endif -typedef struct _Textsecure__WhisperMessage Textsecure__WhisperMessage; -typedef struct _Textsecure__PreKeyWhisperMessage Textsecure__PreKeyWhisperMessage; +typedef struct _Textsecure__SignalMessage Textsecure__SignalMessage; +typedef struct _Textsecure__PreKeySignalMessage Textsecure__PreKeySignalMessage; typedef struct _Textsecure__KeyExchangeMessage Textsecure__KeyExchangeMessage; typedef struct _Textsecure__SenderKeyMessage Textsecure__SenderKeyMessage; typedef struct _Textsecure__SenderKeyDistributionMessage Textsecure__SenderKeyDistributionMessage; +typedef struct _Textsecure__DeviceConsistencyCodeMessage Textsecure__DeviceConsistencyCodeMessage; /* --- enums --- */ @@ -27,7 +28,7 @@ typedef struct _Textsecure__SenderKeyDistributionMessage Textsecure__SenderKeyDi /* --- messages --- */ -struct _Textsecure__WhisperMessage +struct _Textsecure__SignalMessage { ProtobufCMessage base; protobuf_c_boolean has_ratchetkey; @@ -39,12 +40,12 @@ struct _Textsecure__WhisperMessage protobuf_c_boolean has_ciphertext; ProtobufCBinaryData ciphertext; }; -#define TEXTSECURE__WHISPER_MESSAGE__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&textsecure__whisper_message__descriptor) \ +#define TEXTSECURE__SIGNAL_MESSAGE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&textsecure__signal_message__descriptor) \ , 0,{0,NULL}, 0,0, 0,0, 0,{0,NULL} } -struct _Textsecure__PreKeyWhisperMessage +struct _Textsecure__PreKeySignalMessage { ProtobufCMessage base; protobuf_c_boolean has_registrationid; @@ -58,13 +59,13 @@ struct _Textsecure__PreKeyWhisperMessage protobuf_c_boolean has_identitykey; ProtobufCBinaryData identitykey; /* - * WhisperMessage + * SignalMessage */ protobuf_c_boolean has_message; ProtobufCBinaryData message; }; -#define TEXTSECURE__PRE_KEY_WHISPER_MESSAGE__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&textsecure__pre_key_whisper_message__descriptor) \ +#define TEXTSECURE__PRE_KEY_SIGNAL_MESSAGE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&textsecure__pre_key_signal_message__descriptor) \ , 0,0, 0,0, 0,0, 0,{0,NULL}, 0,{0,NULL}, 0,{0,NULL} } @@ -119,43 +120,56 @@ struct _Textsecure__SenderKeyDistributionMessage , 0,0, 0,0, 0,{0,NULL}, 0,{0,NULL} } -/* Textsecure__WhisperMessage methods */ -void textsecure__whisper_message__init - (Textsecure__WhisperMessage *message); -size_t textsecure__whisper_message__get_packed_size - (const Textsecure__WhisperMessage *message); -size_t textsecure__whisper_message__pack - (const Textsecure__WhisperMessage *message, +struct _Textsecure__DeviceConsistencyCodeMessage +{ + ProtobufCMessage base; + protobuf_c_boolean has_generation; + uint32_t generation; + protobuf_c_boolean has_signature; + ProtobufCBinaryData signature; +}; +#define TEXTSECURE__DEVICE_CONSISTENCY_CODE_MESSAGE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&textsecure__device_consistency_code_message__descriptor) \ + , 0,0, 0,{0,NULL} } + + +/* Textsecure__SignalMessage methods */ +void textsecure__signal_message__init + (Textsecure__SignalMessage *message); +size_t textsecure__signal_message__get_packed_size + (const Textsecure__SignalMessage *message); +size_t textsecure__signal_message__pack + (const Textsecure__SignalMessage *message, uint8_t *out); -size_t textsecure__whisper_message__pack_to_buffer - (const Textsecure__WhisperMessage *message, +size_t textsecure__signal_message__pack_to_buffer + (const Textsecure__SignalMessage *message, ProtobufCBuffer *buffer); -Textsecure__WhisperMessage * - textsecure__whisper_message__unpack +Textsecure__SignalMessage * + textsecure__signal_message__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data); -void textsecure__whisper_message__free_unpacked - (Textsecure__WhisperMessage *message, +void textsecure__signal_message__free_unpacked + (Textsecure__SignalMessage *message, ProtobufCAllocator *allocator); -/* Textsecure__PreKeyWhisperMessage methods */ -void textsecure__pre_key_whisper_message__init - (Textsecure__PreKeyWhisperMessage *message); -size_t textsecure__pre_key_whisper_message__get_packed_size - (const Textsecure__PreKeyWhisperMessage *message); -size_t textsecure__pre_key_whisper_message__pack - (const Textsecure__PreKeyWhisperMessage *message, +/* Textsecure__PreKeySignalMessage methods */ +void textsecure__pre_key_signal_message__init + (Textsecure__PreKeySignalMessage *message); +size_t textsecure__pre_key_signal_message__get_packed_size + (const Textsecure__PreKeySignalMessage *message); +size_t textsecure__pre_key_signal_message__pack + (const Textsecure__PreKeySignalMessage *message, uint8_t *out); -size_t textsecure__pre_key_whisper_message__pack_to_buffer - (const Textsecure__PreKeyWhisperMessage *message, +size_t textsecure__pre_key_signal_message__pack_to_buffer + (const Textsecure__PreKeySignalMessage *message, ProtobufCBuffer *buffer); -Textsecure__PreKeyWhisperMessage * - textsecure__pre_key_whisper_message__unpack +Textsecure__PreKeySignalMessage * + textsecure__pre_key_signal_message__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data); -void textsecure__pre_key_whisper_message__free_unpacked - (Textsecure__PreKeyWhisperMessage *message, +void textsecure__pre_key_signal_message__free_unpacked + (Textsecure__PreKeySignalMessage *message, ProtobufCAllocator *allocator); /* Textsecure__KeyExchangeMessage methods */ void textsecure__key_exchange_message__init @@ -214,13 +228,32 @@ Textsecure__SenderKeyDistributionMessage * void textsecure__sender_key_distribution_message__free_unpacked (Textsecure__SenderKeyDistributionMessage *message, ProtobufCAllocator *allocator); +/* Textsecure__DeviceConsistencyCodeMessage methods */ +void textsecure__device_consistency_code_message__init + (Textsecure__DeviceConsistencyCodeMessage *message); +size_t textsecure__device_consistency_code_message__get_packed_size + (const Textsecure__DeviceConsistencyCodeMessage *message); +size_t textsecure__device_consistency_code_message__pack + (const Textsecure__DeviceConsistencyCodeMessage *message, + uint8_t *out); +size_t textsecure__device_consistency_code_message__pack_to_buffer + (const Textsecure__DeviceConsistencyCodeMessage *message, + ProtobufCBuffer *buffer); +Textsecure__DeviceConsistencyCodeMessage * + textsecure__device_consistency_code_message__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void textsecure__device_consistency_code_message__free_unpacked + (Textsecure__DeviceConsistencyCodeMessage *message, + ProtobufCAllocator *allocator); /* --- per-message closures --- */ -typedef void (*Textsecure__WhisperMessage_Closure) - (const Textsecure__WhisperMessage *message, +typedef void (*Textsecure__SignalMessage_Closure) + (const Textsecure__SignalMessage *message, void *closure_data); -typedef void (*Textsecure__PreKeyWhisperMessage_Closure) - (const Textsecure__PreKeyWhisperMessage *message, +typedef void (*Textsecure__PreKeySignalMessage_Closure) + (const Textsecure__PreKeySignalMessage *message, void *closure_data); typedef void (*Textsecure__KeyExchangeMessage_Closure) (const Textsecure__KeyExchangeMessage *message, @@ -231,17 +264,21 @@ typedef void (*Textsecure__SenderKeyMessage_Closure) typedef void (*Textsecure__SenderKeyDistributionMessage_Closure) (const Textsecure__SenderKeyDistributionMessage *message, void *closure_data); +typedef void (*Textsecure__DeviceConsistencyCodeMessage_Closure) + (const Textsecure__DeviceConsistencyCodeMessage *message, + void *closure_data); /* --- services --- */ /* --- descriptors --- */ -extern const ProtobufCMessageDescriptor textsecure__whisper_message__descriptor; -extern const ProtobufCMessageDescriptor textsecure__pre_key_whisper_message__descriptor; +extern const ProtobufCMessageDescriptor textsecure__signal_message__descriptor; +extern const ProtobufCMessageDescriptor textsecure__pre_key_signal_message__descriptor; extern const ProtobufCMessageDescriptor textsecure__key_exchange_message__descriptor; extern const ProtobufCMessageDescriptor textsecure__sender_key_message__descriptor; extern const ProtobufCMessageDescriptor textsecure__sender_key_distribution_message__descriptor; +extern const ProtobufCMessageDescriptor textsecure__device_consistency_code_message__descriptor; PROTOBUF_C__END_DECLS diff --git a/libs/libaxolotl/src/axolotl.def b/libs/libaxolotl/src/axolotl.def deleted file mode 100644 index 5f84f1369d..0000000000 --- a/libs/libaxolotl/src/axolotl.def +++ /dev/null @@ -1,55 +0,0 @@ -LIBRARY libaxolotl.mir - -EXPORTS - axolotl_type_ref - axolotl_type_unref - axolotl_buffer_alloc - axolotl_buffer_create - axolotl_buffer_copy - axolotl_buffer_append - axolotl_buffer_data - axolotl_buffer_len - axolotl_buffer_compare - axolotl_buffer_free - axolotl_buffer_bzero_free - axolotl_buffer_list_alloc - axolotl_buffer_list_push - axolotl_buffer_list_size - axolotl_buffer_list_free - axolotl_int_list_alloc - axolotl_int_list_push_back - axolotl_int_list_size - axolotl_int_list_at - axolotl_int_list_free - axolotl_context_create - axolotl_context_set_crypto_provider - axolotl_context_set_locking_functions - axolotl_context_set_log_function - axolotl_context_destroy - axolotl_store_context_create - axolotl_store_context_set_session_store - axolotl_store_context_set_pre_key_store - axolotl_store_context_set_signed_pre_key_store - axolotl_store_context_set_identity_key_store - axolotl_store_context_set_sender_key_store - axolotl_store_context_destroy - axolotl_session_load_session - axolotl_session_get_sub_device_sessions - axolotl_session_store_session - axolotl_session_contains_session - axolotl_session_delete_session - axolotl_session_delete_all_sessions - axolotl_pre_key_load_key - axolotl_pre_key_store_key - axolotl_pre_key_contains_key - axolotl_pre_key_remove_key - axolotl_signed_pre_key_load_key - axolotl_signed_pre_key_store_key - axolotl_signed_pre_key_contains_key - axolotl_signed_pre_key_remove_key - axolotl_identity_get_key_pair - axolotl_identity_get_local_registration_id - axolotl_identity_save_identity - axolotl_identity_is_trusted_identity - axolotl_sender_key_store_key - axolotl_sender_key_load_key diff --git a/libs/libaxolotl/src/axolotl_internal.h b/libs/libaxolotl/src/axolotl_internal.h deleted file mode 100644 index 3ecddbda7f..0000000000 --- a/libs/libaxolotl/src/axolotl_internal.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef AXOLOTL_INTERNAL_H -#define AXOLOTL_INTERNAL_H - -#include "protobuf-c/protobuf-c.h" -#include "axolotl.h" -#include "LocalStorageProtocol.pb-c.h" - -struct axolotl_type_base { - unsigned int ref_count; - void (*destroy)(axolotl_type_base *instance); -}; - -void axolotl_type_init(axolotl_type_base *instance, - void (*destroy_func)(axolotl_type_base *instance)); - -#define AXOLOTL_INIT(instance, destroy_func) axolotl_type_init((axolotl_type_base *)instance, destroy_func) - -struct axolotl_buffer { - size_t len; - uint8_t data[]; -}; - -struct axolotl_context { - axolotl_crypto_provider crypto_provider; - void (*lock)(void *user_data); - void (*unlock)(void *user_data); - void (*log)(int level, const char *message, size_t len, void *user_data); - void *user_data; -}; - -int axolotl_crypto_random(axolotl_context *context, uint8_t *data, size_t len); -int axolotl_hmac_sha256_init(axolotl_context *context, void **hmac_context, const uint8_t *key, size_t key_len); -int axolotl_hmac_sha256_update(axolotl_context *context, void *hmac_context, const uint8_t *data, size_t data_len); -int axolotl_hmac_sha256_final(axolotl_context *context, void *hmac_context, axolotl_buffer **output); -void axolotl_hmac_sha256_cleanup(axolotl_context *context, void *hmac_context); - -int axolotl_sha512_digest(axolotl_context *context, axolotl_buffer **output, const uint8_t *data, size_t data_len); - -int axolotl_encrypt(axolotl_context *context, - axolotl_buffer **output, - int cipher, - const uint8_t *key, size_t key_len, - const uint8_t *iv, size_t iv_len, - const uint8_t *plaintext, size_t plaintext_len); - -int axolotl_decrypt(axolotl_context *context, - axolotl_buffer **output, - int cipher, - const uint8_t *key, size_t key_len, - const uint8_t *iv, size_t iv_len, - const uint8_t *ciphertext, size_t ciphertext_len); - -void axolotl_lock(axolotl_context *context); -void axolotl_unlock(axolotl_context *context); -void axolotl_log(axolotl_context *context, int level, const char *format, ...); -void axolotl_explicit_bzero(void *v, size_t n); -int axolotl_constant_memcmp(const void *s1, const void *s2, size_t n); - -/*------------------------------------------------------------------------*/ - -/* - * Functions used for internal protocol buffers serialization support. - */ - -int ec_public_key_serialize_protobuf(ProtobufCBinaryData *buffer, const ec_public_key *key); -int ec_private_key_serialize_protobuf(ProtobufCBinaryData *buffer, const ec_private_key *key); - -int ratchet_chain_key_get_key_protobuf(const ratchet_chain_key *chain_key, ProtobufCBinaryData *buffer); -int ratchet_root_key_get_key_protobuf(const ratchet_root_key *root_key, ProtobufCBinaryData *buffer); - -int session_state_serialize_prepare(session_state *state, Textsecure__SessionStructure *session_structure); -void session_state_serialize_prepare_free(Textsecure__SessionStructure *session_structure); -int session_state_deserialize_protobuf(session_state **state, Textsecure__SessionStructure *session_structure, axolotl_context *global_context); - -int sender_key_state_serialize_prepare(sender_key_state *state, Textsecure__SenderKeyStateStructure *state_structure); -void sender_key_state_serialize_prepare_free(Textsecure__SenderKeyStateStructure *state_structure); -int sender_key_state_deserialize_protobuf(sender_key_state **state, Textsecure__SenderKeyStateStructure *state_structure, axolotl_context *global_context); - -void axolotl_str_serialize_protobuf(ProtobufCBinaryData *buffer, const char *str); -char *axolotl_str_deserialize_protobuf(ProtobufCBinaryData *buffer); - -#endif /* AXOLOTL_INTERNAL_H */ diff --git a/libs/libaxolotl/src/curve.c b/libs/libaxolotl/src/curve.c index 241a5b983b..2b666376b9 100644..100755 --- a/libs/libaxolotl/src/curve.c +++ b/libs/libaxolotl/src/curve.c @@ -7,50 +7,58 @@ #include "curve25519/curve25519-donna.h" #include "curve25519/ed25519/additions/curve_sigs.h" -#include "axolotl_internal.h" +#include "curve25519/ed25519/additions/vxeddsa.h" +#include "signal_protocol_internal.h" +#include "utarray.h" #define DJB_TYPE 0x05 #define DJB_KEY_LEN 32 +#define VRF_VERIFY_LEN 32 struct ec_public_key { - axolotl_type_base base; + signal_type_base base; uint8_t data[DJB_KEY_LEN]; }; struct ec_private_key { - axolotl_type_base base; + signal_type_base base; uint8_t data[DJB_KEY_LEN]; }; struct ec_key_pair { - axolotl_type_base base; + signal_type_base base; ec_public_key *public_key; ec_private_key *private_key; }; -int curve_decode_point(ec_public_key **public_key, const uint8_t *key_data, size_t key_len, axolotl_context *global_context) +struct ec_public_key_list +{ + UT_array *values; +}; + +int curve_decode_point(ec_public_key **public_key, const uint8_t *key_data, size_t key_len, signal_context *global_context) { ec_public_key *key = 0; if(key_len > 0 && key_data[0] != DJB_TYPE) { - axolotl_log(global_context, AX_LOG_ERROR, "Invalid key type: %d", key_data[0]); - return AX_ERR_INVALID_KEY; + signal_log(global_context, SG_LOG_ERROR, "Invalid key type: %d", key_data[0]); + return SG_ERR_INVALID_KEY; } if(key_len != DJB_KEY_LEN + 1) { - axolotl_log(global_context, AX_LOG_ERROR, "Invalid key length: %d", key_len); - return AX_ERR_INVALID_KEY; + signal_log(global_context, SG_LOG_ERROR, "Invalid key length: %d", key_len); + return SG_ERR_INVALID_KEY; } key = malloc(sizeof(ec_public_key)); if(!key) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - AXOLOTL_INIT(key, ec_public_key_destroy); + SIGNAL_INIT(key, ec_public_key_destroy); memcpy(key->data, key_data + 1, DJB_KEY_LEN); @@ -71,7 +79,7 @@ int ec_public_key_compare(const ec_public_key *key1, const ec_public_key *key2) return 1; } else { - return axolotl_constant_memcmp(key1->data, key2->data, DJB_KEY_LEN); + return signal_constant_memcmp(key1->data, key2->data, DJB_KEY_LEN); } } @@ -91,17 +99,21 @@ int ec_public_key_memcmp(const ec_public_key *key1, const ec_public_key *key2) } } -int ec_public_key_serialize(axolotl_buffer **buffer, const ec_public_key *key) +int ec_public_key_serialize(signal_buffer **buffer, const ec_public_key *key) { - axolotl_buffer *buf = 0; + signal_buffer *buf = 0; uint8_t *data = 0; - buf = axolotl_buffer_alloc(sizeof(uint8_t) * (DJB_KEY_LEN + 1)); + if(!key) { + return SG_ERR_INVAL; + } + + buf = signal_buffer_alloc(sizeof(uint8_t) * (DJB_KEY_LEN + 1)); if(!buf) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - data = axolotl_buffer_data(buf); + data = signal_buffer_data(buf); data[0] = DJB_TYPE; memcpy(data + 1, key->data, DJB_KEY_LEN); @@ -121,7 +133,7 @@ int ec_public_key_serialize_protobuf(ProtobufCBinaryData *buffer, const ec_publi len = sizeof(uint8_t) * (DJB_KEY_LEN + 1); data = malloc(len); if(!data) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } data[0] = DJB_TYPE; @@ -132,27 +144,27 @@ int ec_public_key_serialize_protobuf(ProtobufCBinaryData *buffer, const ec_publi return 0; } -void ec_public_key_destroy(axolotl_type_base *type) +void ec_public_key_destroy(signal_type_base *type) { ec_public_key *public_key = (ec_public_key *)type; free(public_key); } -int curve_decode_private_point(ec_private_key **private_key, const uint8_t *key_data, size_t key_len, axolotl_context *global_context) +int curve_decode_private_point(ec_private_key **private_key, const uint8_t *key_data, size_t key_len, signal_context *global_context) { ec_private_key *key = 0; if(key_len != DJB_KEY_LEN) { - axolotl_log(global_context, AX_LOG_ERROR, "Invalid key length: %d", key_len); - return AX_ERR_INVALID_KEY; + signal_log(global_context, SG_LOG_ERROR, "Invalid key length: %d", key_len); + return SG_ERR_INVALID_KEY; } key = malloc(sizeof(ec_private_key)); if(!key) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - AXOLOTL_INIT(key, ec_private_key_destroy); + SIGNAL_INIT(key, ec_private_key_destroy); memcpy(key->data, key_data, DJB_KEY_LEN); @@ -173,21 +185,21 @@ int ec_private_key_compare(const ec_private_key *key1, const ec_private_key *key return 1; } else { - return axolotl_constant_memcmp(key1->data, key2->data, DJB_KEY_LEN); + return signal_constant_memcmp(key1->data, key2->data, DJB_KEY_LEN); } } -int ec_private_key_serialize(axolotl_buffer **buffer, const ec_private_key *key) +int ec_private_key_serialize(signal_buffer **buffer, const ec_private_key *key) { - axolotl_buffer *buf = 0; + signal_buffer *buf = 0; uint8_t *data = 0 ; - buf = axolotl_buffer_alloc(sizeof(uint8_t) * DJB_KEY_LEN); + buf = signal_buffer_alloc(sizeof(uint8_t) * DJB_KEY_LEN); if(!buf) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - data = axolotl_buffer_data(buf); + data = signal_buffer_data(buf); memcpy(data, key->data, DJB_KEY_LEN); *buffer = buf; @@ -206,7 +218,7 @@ int ec_private_key_serialize_protobuf(ProtobufCBinaryData *buffer, const ec_priv len = sizeof(uint8_t) * DJB_KEY_LEN; data = malloc(len); if(!data) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memcpy(data, key->data, DJB_KEY_LEN); @@ -216,10 +228,10 @@ int ec_private_key_serialize_protobuf(ProtobufCBinaryData *buffer, const ec_priv return 0; } -void ec_private_key_destroy(axolotl_type_base *type) +void ec_private_key_destroy(signal_type_base *type) { ec_private_key *private_key = (ec_private_key *)type; - axolotl_explicit_bzero(private_key, sizeof(ec_private_key)); + signal_explicit_bzero(private_key, sizeof(ec_private_key)); free(private_key); } @@ -227,14 +239,14 @@ int ec_key_pair_create(ec_key_pair **key_pair, ec_public_key *public_key, ec_pri { ec_key_pair *result = malloc(sizeof(ec_key_pair)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - AXOLOTL_INIT(result, ec_key_pair_destroy); + SIGNAL_INIT(result, ec_key_pair_destroy); result->public_key = public_key; - AXOLOTL_REF(public_key); + SIGNAL_REF(public_key); result->private_key = private_key; - AXOLOTL_REF(private_key); + SIGNAL_REF(private_key); *key_pair = result; @@ -251,15 +263,15 @@ ec_private_key *ec_key_pair_get_private(const ec_key_pair *key_pair) return key_pair->private_key; } -void ec_key_pair_destroy(axolotl_type_base *type) +void ec_key_pair_destroy(signal_type_base *type) { ec_key_pair *key_pair = (ec_key_pair *)type; - AXOLOTL_UNREF(key_pair->public_key); - AXOLOTL_UNREF(key_pair->private_key); + SIGNAL_UNREF(key_pair->public_key); + SIGNAL_UNREF(key_pair->private_key); free(key_pair); } -int curve_generate_private_key(axolotl_context *context, ec_private_key **private_key) +int curve_generate_private_key(signal_context *context, ec_private_key **private_key) { int result = 0; ec_private_key *key = 0; @@ -268,13 +280,13 @@ int curve_generate_private_key(axolotl_context *context, ec_private_key **privat key = malloc(sizeof(ec_private_key)); if(!key) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - AXOLOTL_INIT(key, ec_private_key_destroy); + SIGNAL_INIT(key, ec_private_key_destroy); - result = axolotl_crypto_random(context, key->data, DJB_KEY_LEN); + result = signal_crypto_random(context, key->data, DJB_KEY_LEN); if(result < 0) { goto complete; } @@ -283,9 +295,16 @@ int curve_generate_private_key(axolotl_context *context, ec_private_key **privat key->data[31] &= 127; key->data[31] |= 64; - *private_key = key; - complete: + if(result < 0) { + if(key) { + SIGNAL_UNREF(key); + } + } + else { + *private_key = key; + } + return result; } @@ -296,10 +315,10 @@ int curve_generate_public_key(ec_public_key **public_key, const ec_private_key * ec_public_key *key = malloc(sizeof(ec_public_key)); if(!key) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - AXOLOTL_INIT(key, ec_public_key_destroy); + SIGNAL_INIT(key, ec_public_key_destroy); result = curve25519_donna(key->data, private_key->data, basepoint); @@ -309,13 +328,13 @@ int curve_generate_public_key(ec_public_key **public_key, const ec_private_key * } else { if(key) { - AXOLOTL_UNREF(key); + SIGNAL_UNREF(key); } - return AX_ERR_UNKNOWN; + return SG_ERR_UNKNOWN; } } -int curve_generate_key_pair(axolotl_context *context, ec_key_pair **key_pair) +int curve_generate_key_pair(signal_context *context, ec_key_pair **key_pair) { int result = 0; ec_key_pair *pair_result = 0; @@ -341,15 +360,15 @@ int curve_generate_key_pair(axolotl_context *context, ec_key_pair **key_pair) complete: if(key_public) { - AXOLOTL_UNREF(key_public); + SIGNAL_UNREF(key_public); } if(key_private) { - AXOLOTL_UNREF(key_private); + SIGNAL_UNREF(key_private); } if(result < 0) { if(pair_result) { - AXOLOTL_UNREF(pair_result); + SIGNAL_UNREF(pair_result); } } else { @@ -359,18 +378,110 @@ complete: return result; } +ec_public_key_list *ec_public_key_list_alloc() +{ + ec_public_key_list *list = malloc(sizeof(ec_public_key_list)); + if(!list) { + return 0; + } + memset(list, 0, sizeof(ec_public_key_list)); + utarray_new(list->values, &ut_ptr_icd); + return list; +} + +ec_public_key_list *ec_public_key_list_copy(const ec_public_key_list *list) +{ + ec_public_key_list *result = 0; + unsigned int size; + unsigned int i; + ec_public_key **p; + + result = ec_public_key_list_alloc(); + if(!result) { + return 0; + } + + size = utarray_len(list->values); + + utarray_reserve(result->values, size); + + for (i = 0; i < size; i++) { + p = (ec_public_key **)utarray_eltptr(list->values, i); + ec_public_key_list_push_back(result, *p); + } + + return result; +} + +void ec_public_key_list_push_back(ec_public_key_list *list, ec_public_key *value) +{ + assert(list); + assert(value); + SIGNAL_REF(value); + utarray_push_back(list->values, &value); +} + +unsigned int ec_public_key_list_size(const ec_public_key_list *list) +{ + assert(list); + return utarray_len(list->values); +} + +ec_public_key *ec_public_key_list_at(const ec_public_key_list *list, unsigned int index) +{ + ec_public_key **value = 0; + + assert(list); + assert(index < utarray_len(list->values)); + + value = (ec_public_key **)utarray_eltptr(list->values, index); + + assert(*value); + + return *value; +} + +int ec_public_key_list_sort_comparator(const void *a, const void *b) +{ + const ec_public_key *key1 = *((const ec_public_key **)a); + const ec_public_key *key2 = *((const ec_public_key **)b); + return ec_public_key_memcmp(key1, key2); +} + +void ec_public_key_list_sort(ec_public_key_list *list) +{ + assert(list); + utarray_sort(list->values, ec_public_key_list_sort_comparator); +} + +void ec_public_key_list_free(ec_public_key_list *list) +{ + unsigned int size; + unsigned int i; + ec_public_key **p; + if(list) { + size = utarray_len(list->values); + for (i = 0; i < size; i++) { + p = (ec_public_key **)utarray_eltptr(list->values, i); + SIGNAL_UNREF(*p); + } + utarray_free(list->values); + free(list); + } +} + int curve_calculate_agreement(uint8_t **shared_key_data, const ec_public_key *public_key, const ec_private_key *private_key) { uint8_t *key = 0; int result = 0; if(!public_key || !private_key) { - return AX_ERR_INVALID_KEY; + return SG_ERR_INVALID_KEY; } key = malloc(DJB_KEY_LEN); if(!key) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } result = curve25519_donna(key, private_key->data, public_key->data); @@ -383,7 +494,7 @@ int curve_calculate_agreement(uint8_t **shared_key_data, const ec_public_key *pu if(key) { free(key); } - return AX_ERR_UNKNOWN; + return SG_ERR_UNKNOWN; } } @@ -392,38 +503,38 @@ int curve_verify_signature(const ec_public_key *signing_key, const uint8_t *signature_data, size_t signature_len) { if(signature_len != 64) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } return curve25519_verify(signature_data, signing_key->data, message_data, message_len) == 0; } -int curve_calculate_signature(axolotl_context *context, - axolotl_buffer **signature, +int curve_calculate_signature(signal_context *context, + signal_buffer **signature, const ec_private_key *signing_key, const uint8_t *message_data, size_t message_len) { int result = 0; uint8_t random_data[CURVE_SIGNATURE_LEN]; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; - result = axolotl_crypto_random(context, random_data, sizeof(random_data)); + result = signal_crypto_random(context, random_data, sizeof(random_data)); if(result < 0) { goto complete; } - buffer = axolotl_buffer_alloc(CURVE_SIGNATURE_LEN); + buffer = signal_buffer_alloc(CURVE_SIGNATURE_LEN); if(!buffer) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - result = curve25519_sign(axolotl_buffer_data(buffer), signing_key->data, message_data, message_len, random_data); + result = curve25519_sign(signal_buffer_data(buffer), signing_key->data, message_data, message_len, random_data); complete: if(result < 0) { if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } } else { @@ -431,3 +542,83 @@ complete: } return result; } + +int curve_verify_vrf_signature(signal_context *context, + signal_buffer **vrf_output, + const ec_public_key *signing_key, + const uint8_t *message_data, size_t message_len, + const uint8_t *signature_data, size_t signature_len) +{ + int result = 0; + signal_buffer *buffer = 0; + + if(!signing_key) { + return SG_ERR_INVAL; + } + + if(!message_data || !signature_data || signature_len != 96) { + signal_log(context, SG_LOG_ERROR, "Invalid message or signature format"); + return SG_ERR_VRF_SIG_VERIF_FAILED; + } + + buffer = signal_buffer_alloc(VRF_VERIFY_LEN); + if(!buffer) { + result = SG_ERR_NOMEM; + goto complete; + } + + result = vxed25519_verify(signal_buffer_data(buffer), + signature_data, signing_key->data, + message_data, message_len); + if(result != 0) { + signal_log(context, SG_LOG_ERROR, "Invalid signature"); + result = SG_ERR_VRF_SIG_VERIF_FAILED; + } + +complete: + if(result < 0) { + signal_buffer_free(buffer); + } + else { + *vrf_output = buffer; + } + return result; +} + +int curve_calculate_vrf_signature(signal_context *context, + signal_buffer **signature, + const ec_private_key *signing_key, + const uint8_t *message_data, size_t message_len) +{ + int result = 0; + uint8_t random_data[64]; + signal_buffer *buffer = 0; + + result = signal_crypto_random(context, random_data, sizeof(random_data)); + if(result < 0) { + goto complete; + } + + buffer = signal_buffer_alloc(VRF_SIGNATURE_LEN); + if(!buffer) { + result = SG_ERR_NOMEM; + goto complete; + } + + result = vxed25519_sign(signal_buffer_data(buffer), + signing_key->data, + message_data, message_len, random_data); + if(result != 0) { + signal_log(context, SG_LOG_ERROR, "Signature failed!"); + result = SG_ERR_UNKNOWN; + } + +complete: + if(result < 0) { + signal_buffer_free(buffer); + } + else { + *signature = buffer; + } + return result; +} diff --git a/libs/libaxolotl/src/curve.h b/libs/libaxolotl/src/curve.h index 851d05a319..a4c4488d37 100644 --- a/libs/libaxolotl/src/curve.h +++ b/libs/libaxolotl/src/curve.h @@ -3,15 +3,16 @@ #include <stdint.h> #include <stddef.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { #endif #define CURVE_SIGNATURE_LEN 64 +#define VRF_SIGNATURE_LEN 96 -int curve_decode_point(ec_public_key **public_key, const uint8_t *key_data, size_t key_len, axolotl_context *global_context); +int curve_decode_point(ec_public_key **public_key, const uint8_t *key_data, size_t key_len, signal_context *global_context); int ec_public_key_compare(const ec_public_key *key1, const ec_public_key *key2); int ec_public_key_memcmp(const ec_public_key *key1, const ec_public_key *key2); @@ -22,15 +23,15 @@ int ec_public_key_memcmp(const ec_public_key *key1, const ec_public_key *key2); * * @param buffer Pointer to a buffer that will be allocated by this function * and filled with the contents of the key. The caller is responsible for - * freeing this buffer with axolotl_buffer_free(). + * freeing this buffer with signal_buffer_free(). * @param key Key to serialize * @return 0 on success, negative on failure */ -int ec_public_key_serialize(axolotl_buffer **buffer, const ec_public_key *key); +int ec_public_key_serialize(signal_buffer **buffer, const ec_public_key *key); -void ec_public_key_destroy(axolotl_type_base *type); +void ec_public_key_destroy(signal_type_base *type); -int curve_decode_private_point(ec_private_key **private_key, const uint8_t *key_data, size_t key_len, axolotl_context *global_context); +int curve_decode_private_point(ec_private_key **private_key, const uint8_t *key_data, size_t key_len, signal_context *global_context); int ec_private_key_compare(const ec_private_key *key1, const ec_private_key *key2); /** @@ -40,29 +41,148 @@ int ec_private_key_compare(const ec_private_key *key1, const ec_private_key *key * * @param buffer Pointer to a buffer that will be allocated by this function * and filled with the contents of the key. The caller is responsible for - * freeing this buffer with axolotl_buffer_free(). + * freeing this buffer with signal_buffer_free(). * @param key Key to serialize * @return 0 on success, negative on failure */ -int ec_private_key_serialize(axolotl_buffer **buffer, const ec_private_key *key); +int ec_private_key_serialize(signal_buffer **buffer, const ec_private_key *key); -void ec_private_key_destroy(axolotl_type_base *type); +void ec_private_key_destroy(signal_type_base *type); int ec_key_pair_create(ec_key_pair **key_pair, ec_public_key *public_key, ec_private_key *private_key); ec_public_key *ec_key_pair_get_public(const ec_key_pair *key_pair); ec_private_key *ec_key_pair_get_private(const ec_key_pair *key_pair); -void ec_key_pair_destroy(axolotl_type_base *type); +void ec_key_pair_destroy(signal_type_base *type); -int curve_generate_private_key(axolotl_context *context, ec_private_key **private_key); +int curve_generate_private_key(signal_context *context, ec_private_key **private_key); int curve_generate_public_key(ec_public_key **public_key, const ec_private_key *private_key); -int curve_generate_key_pair(axolotl_context *context, ec_key_pair **key_pair); +/** + * Generates a Curve25519 keypair. + * + * @param key_pair Set to a randomly generated Curve25519 keypair on success. + * @return 0 on success, negative on failure + */ +int curve_generate_key_pair(signal_context *context, ec_key_pair **key_pair); + +/** + * Allocate a new ec_public_key list + * + * @return pointer to the allocated list, or 0 on failure + */ +ec_public_key_list *ec_public_key_list_alloc(void); + +/** + * Copy an ec_public_key list + * + * @return pointer to the copy of the list, or 0 on failure + */ +ec_public_key_list *ec_public_key_list_copy(const ec_public_key_list *list); + +/** + * Push a new value onto the end of the list + * + * @param list the list + * @param value the value to push + */ +void ec_public_key_list_push_back(ec_public_key_list *list, ec_public_key *value); + +/** + * Gets the size of the list. + * + * @param list the list + * @return the size of the list + */ +unsigned int ec_public_key_list_size(const ec_public_key_list *list); + +/** + * Gets the value of the element at a particular index in the list + * + * @param list the list + * @param index the index within the list + * @return the value + */ +ec_public_key *ec_public_key_list_at(const ec_public_key_list *list, unsigned int index); + +/** + * Sorts the list based on a comparison of the key data. + * + * @param list the list + */ +void ec_public_key_list_sort(ec_public_key_list *list); + +/** + * Free the ec_public_key list + * @param list the list to free + */ +void ec_public_key_list_free(ec_public_key_list *list); + +/** + * Calculates an ECDH agreement. + * + * @param shared_key_data Set to a 32-byte shared secret on success. + * @param public_key The Curve25519 (typically remote party's) public key. + * @param private_key The Curve25519 (typically yours) private key. + * @return 0 on success, negative on failure + */ int curve_calculate_agreement(uint8_t **shared_key_data, const ec_public_key *public_key, const ec_private_key *private_key); + +/** + * Verify a Curve25519 signature. + * + * @param signing_key The Curve25519 public key the signature belongs to. + * @param message_data The message that was signed. + * @param message_len The length of the message that was signed. + * @param signature_data The signature to verify. + * @param signature_len The length of the signature to verify. + * @return 1 if valid, 0 if invalid, negative on failure + */ int curve_verify_signature(const ec_public_key *signing_key, const uint8_t *message_data, size_t message_len, const uint8_t *signature_data, size_t signature_len); -int curve_calculate_signature(axolotl_context *context, - axolotl_buffer **signature, + +/** + * Calculates a Curve25519 signature. + * + * @param signature Set to a 64-byte signature on success. + * @param signing_key The private Curve25519 key to create the signature with. + * @param message_data The message to sign. + * @param message_len The length of the message to sign. + * @return 0 on success, negative on failure + */ +int curve_calculate_signature(signal_context *context, + signal_buffer **signature, + const ec_private_key *signing_key, + const uint8_t *message_data, size_t message_len); + +/** + * Verify a Unique Curve25519 signature. + * + * @param vrf_output Set to VRF output on success + * @param signing_key The Curve25519 public key the unique signature belongs to. + * @param message_data The message that was signed. + * @param message_len The length of the message that was signed. + * @param signature_data The signature to verify. + * @param signature_len The length of the signature to verify. + * @return 1 if valid, 0 if invalid, negative on failure + */ +int curve_verify_vrf_signature(signal_context *context, + signal_buffer **vrf_output, + const ec_public_key *signing_key, + const uint8_t *message_data, size_t message_len, + const uint8_t *signature_data, size_t signature_len); + +/** + * Calculates a Unique Curve25519 signature. + * + * @param signature Set to a 96-byte signature on success. + * @param signing_key The private Curve25519 key to create the signature with. + * @param message_data The message to sign. + * @param message_len The length of the message to sign. + * @return 0 on success, negative on failure + */ +int curve_calculate_vrf_signature(signal_context *context, + signal_buffer **signature, const ec_private_key *signing_key, const uint8_t *message_data, size_t message_len); diff --git a/libs/libaxolotl/src/curve25519/CMakeLists.txt b/libs/libaxolotl/src/curve25519/CMakeLists.txt index 50eae030a6..54eb0944ed 100644 --- a/libs/libaxolotl/src/curve25519/CMakeLists.txt +++ b/libs/libaxolotl/src/curve25519/CMakeLists.txt @@ -1,65 +1,104 @@ IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable -Wno-unused-function -Wno-shadow") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable -Wno-unused-function -Wno-shadow") ENDIF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") IF(CMAKE_COMPILER_IS_GNUCC) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-compare -Wno-sign-conversion") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-compare") + IF(GCC_WARN_SIGN_CONVERSION) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-conversion") + ENDIF(GCC_WARN_SIGN_CONVERSION) ENDIF(CMAKE_COMPILER_IS_GNUCC) IF(CMAKE_C_COMPILER_ID MATCHES "Clang") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-shorten-64-to-32") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-shorten-64-to-32") ENDIF(CMAKE_C_COMPILER_ID MATCHES "Clang") +include_directories( + ed25519/nacl_includes + ed25519/additions + ed25519/sha512 + ed25519 +) + set(curve25519_SRCS - curve25519-donna.c + curve25519-donna.c ) set(ed25519_SRCS - ed25519/fe_0.c - ed25519/fe_1.c - ed25519/fe_add.c - ed25519/fe_cmov.c - ed25519/fe_copy.c - ed25519/fe_frombytes.c - ed25519/fe_invert.c - ed25519/fe_isnegative.c - ed25519/fe_isnonzero.c - ed25519/fe_mul.c - ed25519/fe_neg.c - ed25519/fe_pow22523.c - ed25519/fe_sq.c - ed25519/fe_sq2.c - ed25519/fe_sub.c - ed25519/fe_tobytes.c - ed25519/ge_add.c - ed25519/ge_double_scalarmult.c - ed25519/ge_frombytes.c - ed25519/ge_madd.c - ed25519/ge_msub.c - ed25519/ge_p1p1_to_p2.c - ed25519/ge_p1p1_to_p3.c - ed25519/ge_p2_0.c - ed25519/ge_p2_dbl.c - ed25519/ge_p3_0.c - ed25519/ge_p3_dbl.c - ed25519/ge_p3_to_cached.c - ed25519/ge_p3_to_p2.c - ed25519/ge_p3_tobytes.c - ed25519/ge_precomp_0.c - ed25519/ge_scalarmult_base.c - ed25519/ge_sub.c - ed25519/ge_tobytes.c - ed25519/open.c - ed25519/sc_muladd.c - ed25519/sc_reduce.c - ed25519/sign.c - ed25519/additions/compare.c - ed25519/additions/curve_sigs.c - ed25519/additions/sign_modified.c - ed25519/additions/zeroize.c - ed25519/additions/crypto_hash_sha512.h - ed25519/nacl_sha512/blocks.c - ed25519/nacl_sha512/hash.c + ed25519/fe_0.c + ed25519/fe_1.c + ed25519/fe_add.c + ed25519/fe_cmov.c + ed25519/fe_copy.c + ed25519/fe_frombytes.c + ed25519/fe_invert.c + ed25519/fe_isnegative.c + ed25519/fe_isnonzero.c + ed25519/fe_mul.c + ed25519/fe_neg.c + ed25519/fe_pow22523.c + ed25519/fe_sq.c + ed25519/fe_sq2.c + ed25519/fe_sub.c + ed25519/fe_tobytes.c + ed25519/ge_add.c + ed25519/ge_double_scalarmult.c + ed25519/ge_frombytes.c + ed25519/ge_madd.c + ed25519/ge_msub.c + ed25519/ge_p1p1_to_p2.c + ed25519/ge_p1p1_to_p3.c + ed25519/ge_p2_0.c + ed25519/ge_p2_dbl.c + ed25519/ge_p3_0.c + ed25519/ge_p3_dbl.c + ed25519/ge_p3_to_cached.c + ed25519/ge_p3_to_p2.c + ed25519/ge_p3_tobytes.c + ed25519/ge_precomp_0.c + ed25519/ge_scalarmult_base.c + ed25519/ge_sub.c + ed25519/ge_tobytes.c + ed25519/open.c + ed25519/sc_muladd.c + ed25519/sc_reduce.c + ed25519/sign.c + ed25519/additions/compare.c + ed25519/additions/curve_sigs.c + ed25519/additions/elligator.c + ed25519/additions/fe_isequal.c + ed25519/additions/fe_mont_rhs.c + ed25519/additions/fe_montx_to_edy.c + ed25519/additions/fe_sqrt.c + ed25519/additions/ge_is_small_order.c + ed25519/additions/ge_isneutral.c + ed25519/additions/ge_montx_to_p2.c + ed25519/additions/ge_montx_to_p3.c + ed25519/additions/ge_neg.c + ed25519/additions/ge_p3_to_montx.c + ed25519/additions/ge_scalarmult.c + ed25519/additions/ge_scalarmult_cofactor.c + ed25519/additions/keygen.c + ed25519/additions/open_modified.c + ed25519/additions/sc_clamp.c + ed25519/additions/sc_cmov.c + ed25519/additions/sc_neg.c + ed25519/additions/sign_modified.c + ed25519/additions/uopen_modified.c + ed25519/additions/usign_modified.c + ed25519/additions/utility.c + ed25519/additions/vopen_modified.c + ed25519/additions/vsign_modified.c + ed25519/additions/vxeddsa.c + ed25519/additions/xeddsa.c + ed25519/additions/zeroize.c + ed25519/nacl_sha512/blocks.c + ed25519/nacl_sha512/hash.c ) add_library(curve25519 OBJECT ${curve25519_SRCS} ${ed25519_SRCS}) + +# Add -fPIC flag +if(BUILD_SHARED_LIBS) + set_property(TARGET curve25519 PROPERTY POSITION_INDEPENDENT_CODE ON) +endif() diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/crypto_additions.h b/libs/libaxolotl/src/curve25519/ed25519/additions/crypto_additions.h new file mode 100644 index 0000000000..da4a1cd07b --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/crypto_additions.h @@ -0,0 +1,69 @@ + +#ifndef __CRYPTO_ADDITIONS__ +#define __CRYPTO_ADDITIONS__ + +#include "crypto_uint32.h" +#include "fe.h" +#include "ge.h" + +#define MAX_MSG_LEN 256 + +void sc_neg(unsigned char *b, const unsigned char *a); +void sc_cmov(unsigned char* f, const unsigned char* g, unsigned char b); + +int fe_isequal(const fe f, const fe g); +void fe_mont_rhs(fe v2, const fe u); +void fe_montx_to_edy(fe y, const fe u); +void fe_sqrt(fe b, const fe a); + +int ge_is_small_order(const ge_p3 *p); +int ge_isneutral(const ge_p3* q); +void ge_neg(ge_p3* r, const ge_p3 *p); +void ge_montx_to_p3(ge_p3* p, const fe u, const unsigned char ed_sign_bit); +void ge_p3_to_montx(fe u, const ge_p3 *p); +void ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *A); +void ge_scalarmult_cofactor(ge_p3 *q, const ge_p3 *p); + +void elligator(fe u, const fe r); +void hash_to_point(ge_p3* p, const unsigned char* msg, const unsigned long in_len); +void calculate_Bv(ge_p3* Bv, + unsigned char* buf, + const unsigned char* A, + const unsigned char* msg, const unsigned long msg_len); +void calculate_Bv_and_V(ge_p3* Bv, + unsigned char* V, + unsigned char* buf, + const unsigned char* a, + const unsigned char* A, + const unsigned char* msg, const unsigned long msg_len); + +int crypto_sign_modified( + unsigned char *sm, + const unsigned char *m,unsigned long long mlen, + const unsigned char *sk, /* Curve/Ed25519 private key */ + const unsigned char *pk, /* Ed25519 public key */ + const unsigned char *random /* 64 bytes random to hash into nonce */ + ); + +int crypto_sign_open_modified( + unsigned char *m, + const unsigned char *sm,unsigned long long smlen, + const unsigned char *pk + ); + +int crypto_vsign_modified( + unsigned char *sm, + const unsigned char *M,unsigned long Mlen, + const unsigned char *a, + const unsigned char *A, + const unsigned char *random, + const ge_p3 *Bu, + const unsigned char *U); + +int crypto_vsign_open_modified( + unsigned char *m, + const unsigned char *sm,unsigned long long smlen, + const unsigned char *pk, const ge_p3* Bu); + + +#endif diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.c b/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.c index 2a0aa54d4f..7a49b18aaa 100644 --- a/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.c +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.c @@ -3,36 +3,7 @@ #include "ge.h" #include "curve_sigs.h" #include "crypto_sign.h" - -void curve25519_keygen(unsigned char* curve25519_pubkey_out, - const unsigned char* curve25519_privkey_in) -{ - ge_p3 ed; /* Ed25519 pubkey point */ - fe ed_y, ed_y_plus_one, one_minus_ed_y, inv_one_minus_ed_y; - fe mont_x; - - /* Perform a fixed-base multiplication of the Edwards base point, - (which is efficient due to precalculated tables), then convert - to the Curve25519 montgomery-format public key. In particular, - convert Curve25519's "montgomery" x-coordinate into an Ed25519 - "edwards" y-coordinate: - - mont_x = (ed_y + 1) / (1 - ed_y) - - with projective coordinates: - - mont_x = (ed_y + ed_z) / (ed_z - ed_y) - - NOTE: ed_y=1 is converted to mont_x=0 since fe_invert is mod-exp - */ - - ge_scalarmult_base(&ed, curve25519_privkey_in); - fe_add(ed_y_plus_one, ed.Y, ed.Z); - fe_sub(one_minus_ed_y, ed.Z, ed.Y); - fe_invert(inv_one_minus_ed_y, one_minus_ed_y); - fe_mul(mont_x, ed_y_plus_one, inv_one_minus_ed_y); - fe_tobytes(curve25519_pubkey_out, mont_x); -} +#include "crypto_additions.h" int curve25519_sign(unsigned char* signature_out, const unsigned char* curve25519_privkey, @@ -71,18 +42,16 @@ int curve25519_verify(const unsigned char* signature, const unsigned char* curve25519_pubkey, const unsigned char* msg, const unsigned long msg_len) { - fe mont_x, mont_x_minus_one, mont_x_plus_one, inv_mont_x_plus_one; - fe one; - fe ed_y; + fe u; + fe y; unsigned char ed_pubkey[32]; - unsigned long long some_retval; - unsigned char *verifybuf = NULL; /* working buffer */ + unsigned char *verifybuf = NULL; /* working buffer */ unsigned char *verifybuf2 = NULL; /* working buffer #2 */ int result; if ((verifybuf = malloc(msg_len + 64)) == 0) { - result = -1; - goto err; + result = -1; + goto err; } if ((verifybuf2 = malloc(msg_len + 64)) == 0) { @@ -91,22 +60,18 @@ int curve25519_verify(const unsigned char* signature, } /* Convert the Curve25519 public key into an Ed25519 public key. In - particular, convert Curve25519's "montgomery" x-coordinate into an + particular, convert Curve25519's "montgomery" x-coordinate (u) into an Ed25519 "edwards" y-coordinate: - ed_y = (mont_x - 1) / (mont_x + 1) + y = (u - 1) / (u + 1) - NOTE: mont_x=-1 is converted to ed_y=0 since fe_invert is mod-exp + NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp Then move the sign bit into the pubkey from the signature. */ - fe_frombytes(mont_x, curve25519_pubkey); - fe_1(one); - fe_sub(mont_x_minus_one, mont_x, one); - fe_add(mont_x_plus_one, mont_x, one); - fe_invert(inv_mont_x_plus_one, mont_x_plus_one); - fe_mul(ed_y, mont_x_minus_one, inv_mont_x_plus_one); - fe_tobytes(ed_pubkey, ed_y); + fe_frombytes(u, curve25519_pubkey); + fe_montx_to_edy(y, u); + fe_tobytes(ed_pubkey, y); /* Copy the sign bit, and remove it from signature */ ed_pubkey[31] &= 0x7F; /* bit should be zero already, but just in case */ @@ -120,9 +85,8 @@ int curve25519_verify(const unsigned char* signature, /* The below call has a strange API: */ /* verifybuf = R || S || message */ /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets - replaced with pubkey for hashing, then the whole thing gets zeroized - (if bad sig), or contains a copy of msg (good sig) */ - result = crypto_sign_open(verifybuf2, &some_retval, verifybuf, 64 + msg_len, ed_pubkey); + replaced with pubkey for hashing */ + result = crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey); err: diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.h b/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.h index b3dbad0155..a2d819aef0 100644 --- a/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.h +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.h @@ -2,47 +2,16 @@ #ifndef __CURVE_SIGS_H__ #define __CURVE_SIGS_H__ -void curve25519_keygen(unsigned char* curve25519_pubkey_out, /* 32 bytes */ - const unsigned char* curve25519_privkey_in); /* 32 bytes */ - /* returns 0 on success */ int curve25519_sign(unsigned char* signature_out, /* 64 bytes */ const unsigned char* curve25519_privkey, /* 32 bytes */ - const unsigned char* msg, const unsigned long msg_len, + const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */ const unsigned char* random); /* 64 bytes */ /* returns 0 on success */ int curve25519_verify(const unsigned char* signature, /* 64 bytes */ const unsigned char* curve25519_pubkey, /* 32 bytes */ - const unsigned char* msg, const unsigned long msg_len); - -/* helper function - modified version of crypto_sign() to use - explicit private key. In particular: - - sk : private key - pk : public key - msg : message - prefix : 0xFE || [0xFF]*31 - random : 64 bytes random - q : main subgroup order - - The prefix is chosen to distinguish the two SHA512 uses below, since - prefix is an invalid encoding for R (it would encode a "field element" - of 2^255 - 2). 0xFF*32 is set aside for use in ECDH protocols, which - is why the first byte here ix 0xFE. + const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */ - sig_nonce = SHA512(prefix || sk || msg || random) % q - R = g^sig_nonce - M = SHA512(R || pk || m) - S = sig_nonce + (m * sk) - signature = (R || S) - */ -int crypto_sign_modified( - unsigned char *sm, - const unsigned char *m,unsigned long long mlen, - const unsigned char *sk, /* Curve/Ed25519 private key */ - const unsigned char *pk, /* Ed25519 public key */ - const unsigned char *random /* 64 bytes random to hash into nonce */ - ); #endif diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/elligator.c b/libs/libaxolotl/src/curve25519/ed25519/additions/elligator.c new file mode 100644 index 0000000000..8a8131ff2f --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/elligator.c @@ -0,0 +1,111 @@ +#include <string.h> +#include "fe.h" +#include "ge.h" +#include "crypto_uint32.h" +#include "crypto_hash_sha512.h" +#include "crypto_additions.h" + +unsigned int legendre_is_nonsquare(fe in) +{ + fe temp; + fe_pow22523(temp, in); /* temp = in^((q-5)/8) */ + fe_sq(temp, temp); /* in^((q-5)/4) */ + fe_sq(temp, temp); /* in^((q-5)/2) */ + fe_mul(temp, temp, in); /* in^((q-3)/2) */ + fe_mul(temp, temp, in); /* in^((q-1)/2) */ + + /* temp is now the Legendre symbol: + * 1 = square + * 0 = input is zero + * -1 = nonsquare + */ + unsigned char bytes[32]; + fe_tobytes(bytes, temp); + return 1 & bytes[31]; +} + +void elligator(fe u, const fe r) +{ + /* r = input + * x = -A/(1+2r^2) # 2 is nonsquare + * e = (x^3 + Ax^2 + x)^((q-1)/2) # legendre symbol + * if e == 1 (square) or e == 0 (because x == 0 and 2r^2 + 1 == 0) + * u = x + * if e == -1 (nonsquare) + * u = -x - A + */ + fe A, one, twor2, twor2plus1, twor2plus1inv; + fe x, e, Atemp, uneg; + unsigned int nonsquare; + + fe_1(one); + fe_0(A); + A[0] = 486662; /* A = 486662 */ + + fe_sq2(twor2, r); /* 2r^2 */ + fe_add(twor2plus1, twor2, one); /* 1+2r^2 */ + fe_invert(twor2plus1inv, twor2plus1); /* 1/(1+2r^2) */ + fe_mul(x, twor2plus1inv, A); /* A/(1+2r^2) */ + fe_neg(x, x); /* x = -A/(1+2r^2) */ + + fe_mont_rhs(e, x); /* e = x^3 + Ax^2 + x */ + nonsquare = legendre_is_nonsquare(e); + + fe_0(Atemp); + fe_cmov(Atemp, A, nonsquare); /* 0, or A if nonsquare */ + fe_add(u, x, Atemp); /* x, or x+A if nonsquare */ + fe_neg(uneg, u); /* -x, or -x-A if nonsquare */ + fe_cmov(u, uneg, nonsquare); /* x, or -x-A if nonsquare */ +} + +void hash_to_point(ge_p3* p, const unsigned char* in, const unsigned long in_len) +{ + unsigned char hash[64]; + fe h, u; + unsigned char sign_bit; + ge_p3 p3; + + crypto_hash_sha512(hash, in, in_len); + + /* take the high bit as Edwards sign bit */ + sign_bit = (hash[31] & 0x80) >> 7; + hash[31] &= 0x7F; + fe_frombytes(h, hash); + elligator(u, h); + + ge_montx_to_p3(&p3, u, sign_bit); + ge_scalarmult_cofactor(p, &p3); +} + + +void calculate_Bv(ge_p3* Bv, + unsigned char* buf, + const unsigned char* A, + const unsigned char* msg, const unsigned long msg_len) +{ + int count; + + /* Calculate SHA512(label(2) || A || msg) */ + buf[0] = 0xFD; + for (count = 1; count < 32; count++) + buf[count] = 0xFF; + memmove(buf+32, A, 32); + memmove(buf+64, msg, msg_len); + + hash_to_point(Bv, buf, 64 + msg_len); +} + + +void calculate_Bv_and_V(ge_p3* Bv, + unsigned char* V, + unsigned char* buf, + const unsigned char* a, + const unsigned char* A, + const unsigned char* msg, const unsigned long msg_len) +{ + ge_p3 p3; + + calculate_Bv(Bv, buf, A, msg, msg_len); + ge_scalarmult(&p3, a, Bv); + ge_p3_tobytes(V, &p3); +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/fe_isequal.c b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_isequal.c new file mode 100644 index 0000000000..67c5d33c96 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_isequal.c @@ -0,0 +1,14 @@ +#include "fe.h" +#include "crypto_verify_32.h" + +/* +return 1 if f == g +return 0 if f != g +*/ + +int fe_isequal(const fe f, const fe g) +{ + fe h; + fe_sub(h, f, g); + return 1 ^ (1 & (fe_isnonzero(h) >> 8)); +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/fe_mont_rhs.c b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_mont_rhs.c new file mode 100644 index 0000000000..bc8393620c --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_mont_rhs.c @@ -0,0 +1,17 @@ +#include "fe.h" + +void fe_mont_rhs(fe v2, fe u) { + fe A, one; + fe u2, Au, inner; + + fe_1(one); + fe_0(A); + A[0] = 486662; /* A = 486662 */ + + fe_sq(u2, u); /* u^2 */ + fe_mul(Au, A, u); /* Au */ + fe_add(inner, u2, Au); /* u^2 + Au */ + fe_add(inner, inner, one); /* u^2 + Au + 1 */ + fe_mul(v2, u, inner); /* u(u^2 + Au + 1) */ +} + diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/fe_montx_to_edy.c b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_montx_to_edy.c new file mode 100644 index 0000000000..b0f8c63276 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_montx_to_edy.c @@ -0,0 +1,19 @@ + +#include "fe.h" +#include "crypto_additions.h" + +void fe_montx_to_edy(fe y, const fe u) +{ + /* + y = (u - 1) / (u + 1) + + NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp + */ + fe one, um1, up1; + + fe_1(one); + fe_sub(um1, u, one); + fe_add(up1, u, one); + fe_invert(up1, up1); + fe_mul(y, um1, up1); +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/fe_sqrt.c b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_sqrt.c new file mode 100644 index 0000000000..906d38b93e --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_sqrt.c @@ -0,0 +1,50 @@ +#include <assert.h> +#include "fe.h" +#include "crypto_additions.h" + +/* sqrt(-1) */ +static unsigned char i_bytes[32] = { + 0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4, + 0x78, 0xe4, 0x2f, 0xad, 0x06, 0x18, 0x43, 0x2f, + 0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b, + 0x0b, 0xdf, 0xc1, 0x4f, 0x80, 0x24, 0x83, 0x2b +}; + +/* Preconditions: a is square or zero */ + +void fe_sqrt(fe out, const fe a) +{ + fe exp, b, b2, bi, i; + + fe_frombytes(i, i_bytes); + fe_pow22523(exp, a); /* b = a^(q-5)/8 */ + + /* PRECONDITION: legendre symbol == 1 (square) or 0 (a == zero) */ +#ifndef NDEBUG + fe legendre, zero, one; + + fe_sq(legendre, exp); /* in^((q-5)/4) */ + fe_sq(legendre, legendre); /* in^((q-5)/2) */ + fe_mul(legendre, legendre, a); /* in^((q-3)/2) */ + fe_mul(legendre, legendre, a); /* in^((q-1)/2) */ + + fe_0(zero); + fe_1(one); + assert(fe_isequal(legendre, zero) || fe_isequal(legendre, one)); +#endif + + fe_mul(b, a, exp); /* b = a * a^(q-5)/8 */ + fe_sq(b2, b); /* b^2 = a * a^(q-1)/4 */ + + /* note b^4 == a^2, so b^2 == a or -a + * if b^2 != a, multiply it by sqrt(-1) */ + fe_mul(bi, b, i); + fe_cmov(b, bi, 1 ^ fe_isequal(b2, a)); + fe_copy(out, b); + + /* PRECONDITION: out^2 == a */ +#ifndef NDEBUG + fe_sq(b2, out); + assert(fe_isequal(a, b2)); +#endif +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_is_small_order.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_is_small_order.c new file mode 100644 index 0000000000..845941be2a --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_is_small_order.c @@ -0,0 +1,30 @@ +#include "crypto_additions.h" +#include "ge.h" +#include "utility.h" +#include "stdio.h" + +/* +return 1 if f == g +return 0 if f != g +*/ + +int ge_is_small_order(const ge_p3 *p) +{ + ge_p1p1 p1p1; + ge_p2 p2; + fe zero; + + ge_p3_dbl(&p1p1, p); + ge_p1p1_to_p2(&p2, &p1p1); + + ge_p2_dbl(&p1p1, &p2); + ge_p1p1_to_p2(&p2, &p1p1); + + ge_p2_dbl(&p1p1, &p2); + ge_p1p1_to_p2(&p2, &p1p1); + + fe_0(zero); + + /* Check if 8*p == neutral element == (0, 1) */ + return (fe_isequal(p2.X, zero) & fe_isequal(p2.Y, p2.Z)); +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_isneutral.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_isneutral.c new file mode 100644 index 0000000000..d40e443682 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_isneutral.c @@ -0,0 +1,16 @@ +#include "crypto_additions.h" +#include "ge.h" + +/* +return 1 if p is the neutral point +return 0 otherwise +*/ + +int ge_isneutral(const ge_p3 *p) +{ + fe zero; + fe_0(zero); + + /* Check if p == neutral element == (0, 1) */ + return (fe_isequal(p->X, zero) & fe_isequal(p->Y, p->Z)); +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p2.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p2.c new file mode 100644 index 0000000000..d123d03580 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p2.c @@ -0,0 +1,69 @@ +#include "fe.h" +#include "ge.h" +#include "assert.h" +#include "crypto_additions.h" +#include "utility.h" + +/* sqrt(-(A+2)) */ +static unsigned char A_bytes[32] = { + 0x06, 0x7e, 0x45, 0xff, 0xaa, 0x04, 0x6e, 0xcc, + 0x82, 0x1a, 0x7d, 0x4b, 0xd1, 0xd3, 0xa1, 0xc5, + 0x7e, 0x4f, 0xfc, 0x03, 0xdc, 0x08, 0x7b, 0xd2, + 0xbb, 0x06, 0xa0, 0x60, 0xf4, 0xed, 0x26, 0x0f +}; + +void ge_montx_to_p2(ge_p2* p, const fe u, const unsigned char ed_sign_bit) +{ + fe x, y, A, v, v2, iv, nx; + + fe_frombytes(A, A_bytes); + + /* given u, recover edwards y */ + /* given u, recover v */ + /* given u and v, recover edwards x */ + + fe_montx_to_edy(y, u); /* y = (u - 1) / (u + 1) */ + + fe_mont_rhs(v2, u); /* v^2 = u(u^2 + Au + 1) */ + fe_sqrt(v, v2); /* v = sqrt(v^2) */ + + fe_mul(x, u, A); /* x = u * sqrt(-(A+2)) */ + fe_invert(iv, v); /* 1/v */ + fe_mul(x, x, iv); /* x = (u/v) * sqrt(-(A+2)) */ + + fe_neg(nx, x); /* negate x to match sign bit */ + fe_cmov(x, nx, fe_isnegative(x) ^ ed_sign_bit); + + fe_copy(p->X, x); + fe_copy(p->Y, y); + fe_1(p->Z); + + /* POSTCONDITION: check that p->X and p->Y satisfy the Ed curve equation */ + /* -x^2 + y^2 = 1 + dx^2y^2 */ +#ifndef NDEBUG + { + fe one, d, x2, y2, x2y2, dx2y2; + + unsigned char dbytes[32] = { + 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, + 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, + 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, + 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52 + }; + + fe_frombytes(d, dbytes); + fe_1(one); + fe_sq(x2, p->X); /* x^2 */ + fe_sq(y2, p->Y); /* y^2 */ + + fe_mul(dx2y2, x2, y2); /* x^2y^2 */ + fe_mul(dx2y2, dx2y2, d); /* dx^2y^2 */ + fe_add(dx2y2, dx2y2, one); /* dx^2y^2 + 1 */ + + fe_neg(x2y2, x2); /* -x^2 */ + fe_add(x2y2, x2y2, y2); /* -x^2 + y^2 */ + + assert(fe_isequal(x2y2, dx2y2)); + } +#endif +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p3.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p3.c new file mode 100644 index 0000000000..7a716c5a72 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p3.c @@ -0,0 +1,70 @@ +#include "fe.h" +#include "ge.h" +#include "assert.h" +#include "crypto_additions.h" +#include "utility.h" + +/* sqrt(-(A+2)) */ +static unsigned char A_bytes[32] = { + 0x06, 0x7e, 0x45, 0xff, 0xaa, 0x04, 0x6e, 0xcc, + 0x82, 0x1a, 0x7d, 0x4b, 0xd1, 0xd3, 0xa1, 0xc5, + 0x7e, 0x4f, 0xfc, 0x03, 0xdc, 0x08, 0x7b, 0xd2, + 0xbb, 0x06, 0xa0, 0x60, 0xf4, 0xed, 0x26, 0x0f +}; + +void ge_montx_to_p3(ge_p3* p, const fe u, const unsigned char ed_sign_bit) +{ + fe x, y, A, v, v2, iv, nx; + + fe_frombytes(A, A_bytes); + + /* given u, recover edwards y */ + /* given u, recover v */ + /* given u and v, recover edwards x */ + + fe_montx_to_edy(y, u); /* y = (u - 1) / (u + 1) */ + + fe_mont_rhs(v2, u); /* v^2 = u(u^2 + Au + 1) */ + fe_sqrt(v, v2); /* v = sqrt(v^2) */ + + fe_mul(x, u, A); /* x = u * sqrt(-(A+2)) */ + fe_invert(iv, v); /* 1/v */ + fe_mul(x, x, iv); /* x = (u/v) * sqrt(-(A+2)) */ + + fe_neg(nx, x); /* negate x to match sign bit */ + fe_cmov(x, nx, fe_isnegative(x) ^ ed_sign_bit); + + fe_copy(p->X, x); + fe_copy(p->Y, y); + fe_1(p->Z); + fe_mul(p->T, p->X, p->Y); + + /* POSTCONDITION: check that p->X and p->Y satisfy the Ed curve equation */ + /* -x^2 + y^2 = 1 + dx^2y^2 */ +#ifndef NDEBUG + { + fe one, d, x2, y2, x2y2, dx2y2; + + unsigned char dbytes[32] = { + 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, + 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, + 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, + 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52 + }; + + fe_frombytes(d, dbytes); + fe_1(one); + fe_sq(x2, p->X); /* x^2 */ + fe_sq(y2, p->Y); /* y^2 */ + + fe_mul(dx2y2, x2, y2); /* x^2y^2 */ + fe_mul(dx2y2, dx2y2, d); /* dx^2y^2 */ + fe_add(dx2y2, dx2y2, one); /* dx^2y^2 + 1 */ + + fe_neg(x2y2, x2); /* -x^2 */ + fe_add(x2y2, x2y2, y2); /* -x^2 + y^2 */ + + assert(fe_isequal(x2y2, dx2y2)); + } +#endif +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_neg.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_neg.c new file mode 100644 index 0000000000..d679713fe0 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_neg.c @@ -0,0 +1,15 @@ +#include "crypto_additions.h" +#include "ge.h" + +/* +return r = -p +*/ + + +void ge_neg(ge_p3* r, const ge_p3 *p) +{ + fe_neg(r->X, p->X); + fe_copy(r->Y, p->Y); + fe_copy(r->Z, p->Z); + fe_neg(r->T, p->T); +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_p3_to_montx.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_p3_to_montx.c new file mode 100644 index 0000000000..b539b2f17f --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_p3_to_montx.c @@ -0,0 +1,21 @@ +#include "fe.h" +#include "crypto_additions.h" + +void ge_p3_to_montx(fe u, const ge_p3 *ed) +{ + /* + u = (y + 1) / (1 - y) + or + u = (y + z) / (z - y) + + NOTE: y=1 is converted to u=0 since fe_invert is mod-exp + */ + + fe y_plus_one, one_minus_y, inv_one_minus_y; + + fe_add(y_plus_one, ed->Y, ed->Z); + fe_sub(one_minus_y, ed->Z, ed->Y); + fe_invert(inv_one_minus_y, one_minus_y); + fe_mul(u, y_plus_one, inv_one_minus_y); +} + diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult.c new file mode 100644 index 0000000000..e4f741b8d8 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult.c @@ -0,0 +1,140 @@ +#include "crypto_uint32.h" +#include "ge.h" +#include "crypto_additions.h" + +static unsigned char equal(signed char b,signed char c) +{ + unsigned char ub = b; + unsigned char uc = c; + unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ + crypto_uint32 y = x; /* 0: yes; 1..255: no */ + y -= 1; /* 4294967295: yes; 0..254: no */ + y >>= 31; /* 1: yes; 0: no */ + return y; +} + +static unsigned char negative(signed char b) +{ + unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ + x >>= 63; /* 1: yes; 0: no */ + return x; +} + +static void cmov(ge_cached *t,const ge_cached *u,unsigned char b) +{ + fe_cmov(t->YplusX,u->YplusX,b); + fe_cmov(t->YminusX,u->YminusX,b); + fe_cmov(t->Z,u->Z,b); + fe_cmov(t->T2d,u->T2d,b); +} + +static void select(ge_cached *t,const ge_cached *pre, signed char b) +{ + ge_cached minust; + unsigned char bnegative = negative(b); + unsigned char babs = b - (((-bnegative) & b) << 1); + + fe_1(t->YplusX); + fe_1(t->YminusX); + fe_1(t->Z); + fe_0(t->T2d); + + cmov(t,pre+0,equal(babs,1)); + cmov(t,pre+1,equal(babs,2)); + cmov(t,pre+2,equal(babs,3)); + cmov(t,pre+3,equal(babs,4)); + cmov(t,pre+4,equal(babs,5)); + cmov(t,pre+5,equal(babs,6)); + cmov(t,pre+6,equal(babs,7)); + cmov(t,pre+7,equal(babs,8)); + fe_copy(minust.YplusX,t->YminusX); + fe_copy(minust.YminusX,t->YplusX); + fe_copy(minust.Z,t->Z); + fe_neg(minust.T2d,t->T2d); + cmov(t,&minust,bnegative); +} + +/* +h = a * B +where a = a[0]+256*a[1]+...+256^31 a[31] +B is the Ed25519 base point (x,4/5) with x positive. + +Preconditions: + a[31] <= 127 +*/ + +void ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *A) +{ + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_p3 t0, t1, t2; + ge_cached t, pre[8]; + int i; + + for (i = 0;i < 32;++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0;i < 63;++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + e[63] += carry; + /* each e[i] is between -8 and 8 */ + + // Precomputation: + ge_p3_to_cached(pre+0, A); // A + + ge_p3_dbl(&r, A); + ge_p1p1_to_p3(&t0, &r); + ge_p3_to_cached(pre+1, &t0); // 2A + + ge_add(&r, A, pre+1); + ge_p1p1_to_p3(&t1, &r); + ge_p3_to_cached(pre+2, &t1); // 3A + + ge_p3_dbl(&r, &t0); + ge_p1p1_to_p3(&t0, &r); + ge_p3_to_cached(pre+3, &t0); // 4A + + ge_add(&r, A, pre+3); + ge_p1p1_to_p3(&t2, &r); + ge_p3_to_cached(pre+4, &t2); // 5A + + ge_p3_dbl(&r, &t1); + ge_p1p1_to_p3(&t1, &r); + ge_p3_to_cached(pre+5, &t1); // 6A + + ge_add(&r, A, pre+5); + ge_p1p1_to_p3(&t1, &r); + ge_p3_to_cached(pre+6, &t1); // 7A + + ge_p3_dbl(&r, &t0); + ge_p1p1_to_p3(&t0, &r); + ge_p3_to_cached(pre+7, &t0); // 8A + + ge_p3_0(h); + + for (i = 63;i > 0; i--) { + select(&t,pre,e[i]); + ge_add(&r, h, &t); + ge_p1p1_to_p2(&s,&r); + + ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); + ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); + ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); + ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); + + } + select(&t,pre,e[0]); + ge_add(&r, h, &t); + ge_p1p1_to_p3(h,&r); +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult_cofactor.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult_cofactor.c new file mode 100644 index 0000000000..6affbb05d5 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult_cofactor.c @@ -0,0 +1,21 @@ +#include "crypto_additions.h" +#include "ge.h" + +/* +return 8 * p +*/ + +void ge_scalarmult_cofactor(ge_p3 *q, const ge_p3 *p) +{ + ge_p1p1 p1p1; + ge_p2 p2; + + ge_p3_dbl(&p1p1, p); + ge_p1p1_to_p2(&p2, &p1p1); + + ge_p2_dbl(&p1p1, &p2); + ge_p1p1_to_p2(&p2, &p1p1); + + ge_p2_dbl(&p1p1, &p2); + ge_p1p1_to_p3(q, &p1p1); +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.c b/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.c new file mode 100644 index 0000000000..de7cdcd598 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.c @@ -0,0 +1,21 @@ +#include "ge.h" +#include "keygen.h" +#include "crypto_additions.h" + +void curve25519_keygen(unsigned char* curve25519_pubkey_out, + const unsigned char* curve25519_privkey_in) +{ + /* Perform a fixed-base multiplication of the Edwards base point, + (which is efficient due to precalculated tables), then convert + to the Curve25519 montgomery-format public key. + + NOTE: y=1 is converted to u=0 since fe_invert is mod-exp + */ + + ge_p3 ed; /* Ed25519 pubkey point */ + fe u; + + ge_scalarmult_base(&ed, curve25519_privkey_in); + ge_p3_to_montx(u, &ed); + fe_tobytes(curve25519_pubkey_out, u); +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.h b/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.h new file mode 100644 index 0000000000..e86e7c5582 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.h @@ -0,0 +1,12 @@ + +#ifndef __KEYGEN_H__ +#define __KEYGEN_H__ + +/* Sets and clears bits to make a random 32 bytes into a private key */ +void sc_clamp(unsigned char* a); + +/* The private key should be 32 random bytes "clamped" by sc_clamp() */ +void curve25519_keygen(unsigned char* curve25519_pubkey_out, /* 32 bytes */ + const unsigned char* curve25519_privkey_in); /* 32 bytes */ + +#endif diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/open_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/open_modified.c new file mode 100644 index 0000000000..a156098191 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/open_modified.c @@ -0,0 +1,45 @@ +#include <string.h> +#include "crypto_sign.h" +#include "crypto_hash_sha512.h" +#include "crypto_verify_32.h" +#include "ge.h" +#include "sc.h" +#include "crypto_additions.h" + +int crypto_sign_open_modified( + unsigned char *m, + const unsigned char *sm,unsigned long long smlen, + const unsigned char *pk +) +{ + unsigned char pkcopy[32]; + unsigned char rcopy[32]; + unsigned char scopy[32]; + unsigned char h[64]; + unsigned char rcheck[32]; + ge_p3 A; + ge_p2 R; + + if (smlen < 64) goto badsig; + if (sm[63] & 224) goto badsig; /* strict parsing of s */ + if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; + + memmove(pkcopy,pk,32); + memmove(rcopy,sm,32); + memmove(scopy,sm + 32,32); + + memmove(m,sm,smlen); + memmove(m + 32,pkcopy,32); + crypto_hash_sha512(h,m,smlen); + sc_reduce(h); + + ge_double_scalarmult_vartime(&R,h,&A,scopy); + ge_tobytes(rcheck,&R); + + if (crypto_verify_32(rcheck,rcopy) == 0) { + return 0; + } + +badsig: + return -1; +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/sc_clamp.c b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_clamp.c new file mode 100644 index 0000000000..7788be9071 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_clamp.c @@ -0,0 +1,8 @@ +#include "crypto_additions.h" + +void sc_clamp(unsigned char* a) +{ + a[0] &= 248; + a[31] &= 127; + a[31] |= 64; +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/sc_cmov.c b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_cmov.c new file mode 100644 index 0000000000..443a5bb71e --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_cmov.c @@ -0,0 +1,21 @@ +#include "crypto_additions.h" + +/* +Replace (f,g) with (g,g) if b == 1; +replace (f,g) with (f,g) if b == 0. + +Preconditions: b in {0,1}. +*/ + +void sc_cmov(unsigned char* f, const unsigned char* g, unsigned char b) +{ + int count=32; + unsigned char x[32]; + for (count=0; count < 32; count++) + x[count] = f[count] ^ g[count]; + b = -b; + for (count=0; count < 32; count++) + x[count] &= b; + for (count=0; count < 32; count++) + f[count] = f[count] ^ x[count]; +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/sc_neg.c b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_neg.c new file mode 100644 index 0000000000..ef407d405e --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_neg.c @@ -0,0 +1,25 @@ +#include <string.h> +#include "crypto_additions.h" +#include "sc.h" + +/* l = order of base point = 2^252 + 27742317777372353535851937790883648493 */ + +/* +static unsigned char l[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x10}; +*/ + +static unsigned char lminus1[32] = {0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; + +/* b = -a (mod l) */ +void sc_neg(unsigned char *b, const unsigned char *a) +{ + unsigned char zero[32]; + memset(zero, 0, 32); + sc_muladd(b, lminus1, a, zero); /* b = (-1)a + 0 (mod l) */ +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/sign_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/sign_modified.c index 61332e70e7..b2fb8c20d3 100644 --- a/libs/libaxolotl/src/curve25519/ed25519/additions/sign_modified.c +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/sign_modified.c @@ -4,6 +4,7 @@ #include "ge.h" #include "sc.h" #include "zeroize.h" +#include "crypto_additions.h" /* NEW: Compare to pristine crypto_sign() Uses explicit private key for nonce derivation and as scalar, @@ -36,6 +37,7 @@ int crypto_sign_modified( memmove(sm + 32,pk,32); sc_reduce(nonce); + ge_scalarmult_base(&R,nonce); ge_p3_tobytes(sm,&R); @@ -43,5 +45,9 @@ int crypto_sign_modified( sc_reduce(hram); sc_muladd(sm + 32,hram,sk,nonce); /* NEW: Use privkey directly */ + /* Erase any traces of private scalar or + nonce left in the stack from sc_muladd */ + zeroize_stack(); + zeroize(nonce, 64); return 0; } diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c new file mode 100644 index 0000000000..412f8c4c9b --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c @@ -0,0 +1,100 @@ +#include <string.h> +#include "sc.h" +#include "ge.h" +#include "crypto_hash_sha512.h" +#include "crypto_verify_32.h" +#include "crypto_additions.h" +#include "crypto_sign.h" + +int crypto_usign_open_modified( + unsigned char *m,unsigned long long *mlen, + const unsigned char *sm,unsigned long long smlen, + const unsigned char *pk, const ge_p3* Bu +) +{ + ge_p3 U; + unsigned char h[64]; + unsigned char s[64]; + unsigned char strict[64]; + ge_p3 A; + ge_p2 R; + unsigned char hcheck[64]; + int count; + + if (smlen < 96) goto badsig; + if (sm[63] & 224) goto badsig; /* strict parsing of h */ + if (sm[95] & 224) goto badsig; /* strict parsing of s */ + + /* Load -A */ + if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; + + /* Load -U, h, s */ + ge_frombytes_negate_vartime(&U, sm); + memset(h, 0, 64); + memset(s, 0, 64); + memmove(h, sm + 32, 32); + memmove(s, sm + 64, 32); + + /* Insist that s and h are reduced scalars (strict parsing) */ + memcpy(strict, h, 64); + sc_reduce(strict); + if (memcmp(strict, h, 32) != 0) + goto badsig; + memcpy(strict, s, 64); + sc_reduce(strict); + if (memcmp(strict, s, 32) != 0) + goto badsig; + + /* Reject U (actually -U) if small order */ + if (ge_is_small_order(&U)) + goto badsig; + + // R = sB + h(-A) + ge_double_scalarmult_vartime(&R,h,&A,s); + + // Ru = sBu + h(-U) + ge_p3 sBu, hU; + + // sBu + ge_scalarmult(&sBu, s, Bu); + + // h(-U) + ge_scalarmult(&hU, h, &U); + + // Ru = sBu + h(-U) + ge_p1p1 Rp1p1; + ge_p3 Ru; + ge_cached hUcached; + ge_p3_to_cached(&hUcached, &hU); + ge_add(&Rp1p1, &sBu, &hUcached); + ge_p1p1_to_p3(&Ru, &Rp1p1); + + + // Check h == SHA512(label(4) || A || U || R || Ru || M) + m[0] = 0xFB; + for (count = 1; count < 32; count++) + m[count] = 0xFF; + memmove(m+32, pk, 32); + /* undo the negation for U */ + fe_neg(U.X, U.X); + fe_neg(U.T, U.T); + ge_p3_tobytes(m+64, &U); + ge_tobytes(m+96, &R); + ge_p3_tobytes(m+128, &Ru); + memmove(m+160, sm+96, smlen - 96); + + crypto_hash_sha512(hcheck, m, smlen + 64); + sc_reduce(hcheck); + + if (crypto_verify_32(hcheck, h) == 0) { + memmove(m,m + 64,smlen - 64); + memset(m + smlen - 64,0,64); + *mlen = smlen - 64; + return 0; + } + +badsig: + *mlen = -1; + memset(m,0,smlen); + return -1; +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/usign_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/usign_modified.c new file mode 100644 index 0000000000..3bbd871b7a --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/usign_modified.c @@ -0,0 +1,62 @@ +#include <string.h> +#include "crypto_sign.h" +#include "crypto_hash_sha512.h" +#include "ge.h" +#include "sc.h" +#include "zeroize.h" +#include "crypto_additions.h" + +/* NEW: Compare to pristine crypto_sign() + Uses explicit private key for nonce derivation and as scalar, + instead of deriving both from a master key. +*/ +int crypto_usign_modified( + unsigned char *sm, + const unsigned char *M,unsigned long Mlen, + const unsigned char *a, + const unsigned char *A, + const unsigned char *random, + const ge_p3 *Bu, + const unsigned char *U +) +{ + unsigned char r[64]; + unsigned char h[64]; + ge_p3 R, Ru; + int count=0; + + /* r = SHA512(label(3) || a || U || random(64)) */ + sm[0] = 0xFC; + for (count = 1; count < 32; count++) + sm[count] = 0xFF; + + memmove(sm + 32, a, 32); /* Use privkey directly for nonce derivation */ + memmove(sm + 64, U, 32); + + memmove(sm + 96, random, 64); /* Add suffix of random data */ + crypto_hash_sha512(r, sm, 160); + + sc_reduce(r); + ge_scalarmult_base(&R, r); + ge_scalarmult(&Ru, r, Bu); + + /* h = SHA512(label(4) || A || U || R || Ru || M) */ + sm[0] = 0xFB; + memmove(sm + 32, A, 32); + memmove(sm + 64, U, 32); + ge_p3_tobytes(sm+96, &R); + ge_p3_tobytes(sm+128, &Ru); + memmove(sm + 160, M, Mlen); + + crypto_hash_sha512(h, sm, Mlen + 160); + sc_reduce(h); + + memmove(sm, h, 32); /* Write h */ + sc_muladd(sm + 32, h, a, r); /* Write s */ + + /* Erase any traces of private scalar or + nonce left in the stack from sc_muladd. */ + zeroize_stack(); + zeroize(r, 64); + return 0; +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/utility.c b/libs/libaxolotl/src/curve25519/ed25519/additions/utility.c new file mode 100644 index 0000000000..c59099a9e3 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/utility.c @@ -0,0 +1,29 @@ +#include <stdlib.h> +#include <stdio.h> +#include "utility.h" + +void print_vector(const char* name, const unsigned char* v) +{ + int count; + printf("%s = \n", name); + for (count = 0; count < 32; count++) + printf("%02x ", v[count]); + printf("\n"); +} + +void print_bytes(const char* name, const unsigned char* v, int numbytes) +{ + int count; + printf("%s = \n", name); + for (count = 0; count < numbytes; count++) + printf("%02x ", v[count]); + printf("\n"); +} + +void print_fe(const char* name, const fe in) +{ + unsigned char bytes[32]; + fe_tobytes(bytes, in); + print_vector(name, bytes); +} + diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/utility.h b/libs/libaxolotl/src/curve25519/ed25519/additions/utility.h new file mode 100644 index 0000000000..35348782df --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/utility.h @@ -0,0 +1,11 @@ + +#ifndef __UTILITY_H__ +#define __UTILITY_H__ + +#include "fe.h" + +void print_vector(const char* name, const unsigned char* v); +void print_bytes(const char* name, const unsigned char* v, int numbytes); +void print_fe(const char* name, const fe in); + +#endif diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c new file mode 100644 index 0000000000..3dfc7fba6f --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c @@ -0,0 +1,85 @@ +#include <string.h> +#include "sc.h" +#include "ge.h" +#include "crypto_hash_sha512.h" +#include "crypto_verify_32.h" +#include "crypto_additions.h" +#include "crypto_sign.h" + +int crypto_vsign_open_modified( + unsigned char *m, + const unsigned char *sm,unsigned long long smlen, + const unsigned char *pk, const ge_p3* Bv +) +{ + ge_p3 Vneg, V, Aneg, A, c_V, c_A, h_Vneg, s_Bv; + unsigned char h[32]; + unsigned char s[32]; + ge_p2 R; + unsigned char hcheck[64]; + unsigned char vrf_output[64]; + int count; + + if (smlen < 96) goto badsig; + if (sm[63] & 224) goto badsig; /* strict parsing of h */ + if (sm[95] & 224) goto badsig; /* strict parsing of s */ + + /* Load -A */ + if (ge_frombytes_negate_vartime(&Aneg,pk) != 0) goto badsig; + + /* Load -V, h, s */ + if (ge_frombytes_negate_vartime(&Vneg, sm) != 0) goto badsig; + memmove(h, sm + 32, 32); + memmove(s, sm + 64, 32); + if (h[31] & 224) goto badsig; /* strict parsing of h */ + if (s[31] & 224) goto badsig; /* strict parsing of s */ + + ge_neg(&A, &Aneg); + ge_neg(&V, &Vneg); + ge_scalarmult_cofactor(&c_A, &A); + ge_scalarmult_cofactor(&c_V, &V); + if (ge_isneutral(&c_A) || ge_isneutral(&c_V) || ge_isneutral(Bv)) + goto badsig; + + // R = (s*B) + (h * -A)) + ge_double_scalarmult_vartime(&R, h, &Aneg, s); + + // s * Bv + ge_scalarmult(&s_Bv, s, Bv); + + // h * -V + ge_scalarmult(&h_Vneg, h, &Vneg); + + // Rv = (sc * Bv) + (hc * (-V)) + ge_p1p1 Rp1p1; + ge_p3 Rv; + ge_cached h_Vnegcached; + ge_p3_to_cached(&h_Vnegcached, &h_Vneg); + ge_add(&Rp1p1, &s_Bv, &h_Vnegcached); + ge_p1p1_to_p3(&Rv, &Rp1p1); + + // Check h == SHA512(label(4) || A || V || R || Rv || M) + m[0] = 0xFB; // label 4 + for (count = 1; count < 32; count++) + m[count] = 0xFF; + memmove(m+32, pk, 32); + ge_p3_tobytes(m+64, &V); + ge_tobytes(m+96, &R); + ge_p3_tobytes(m+128, &Rv); + memmove(m+160, sm+96, smlen - 96); + + crypto_hash_sha512(hcheck, m, smlen + 64); + sc_reduce(hcheck); + + if (crypto_verify_32(hcheck, h) == 0) { + ge_p3_tobytes(m+32, &c_V); + m[0] = 0xFA; // label 5 + crypto_hash_sha512(vrf_output, m, 64); + memmove(m, vrf_output, 32); + return 0; + } + +badsig: + memset(m, 0, 32); + return -1; +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/vsign_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/vsign_modified.c new file mode 100644 index 0000000000..518b851d63 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/vsign_modified.c @@ -0,0 +1,62 @@ +#include <string.h> +#include "crypto_sign.h" +#include "crypto_hash_sha512.h" +#include "ge.h" +#include "sc.h" +#include "zeroize.h" +#include "crypto_additions.h" + +/* NEW: Compare to pristine crypto_sign() + Uses explicit private key for nonce derivation and as scalar, + instead of deriving both from a master key. +*/ +int crypto_vsign_modified( + unsigned char *sm, + const unsigned char *M,unsigned long Mlen, + const unsigned char *a, + const unsigned char *A, + const unsigned char *random, + const ge_p3 *Bv, + const unsigned char *V +) +{ + unsigned char r[64]; + unsigned char h[64]; + ge_p3 R, Rv; + int count=0; + + /* r = SHA512(label(3) || a || V || random(64)) */ + sm[0] = 0xFC; + for (count = 1; count < 32; count++) + sm[count] = 0xFF; + + memmove(sm + 32, a, 32); /* Use privkey directly for nonce derivation */ + memmove(sm + 64, V, 32); + + memmove(sm + 96, random, 64); /* Add suffix of random data */ + crypto_hash_sha512(r, sm, 160); + + sc_reduce(r); + ge_scalarmult_base(&R, r); + ge_scalarmult(&Rv, r, Bv); + + /* h = SHA512(label(4) || A || V || R || Rv || M) */ + sm[0] = 0xFB; + memmove(sm + 32, A, 32); + memmove(sm + 64, V, 32); + ge_p3_tobytes(sm+96, &R); + ge_p3_tobytes(sm+128, &Rv); + memmove(sm + 160, M, Mlen); + + crypto_hash_sha512(h, sm, Mlen + 160); + sc_reduce(h); + + memmove(sm, h, 32); /* Write h */ + sc_muladd(sm + 32, h, a, r); /* Write s */ + + /* Erase any traces of private scalar or + nonce left in the stack from sc_muladd. */ + zeroize_stack(); + zeroize(r, 64); + return 0; +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.c b/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.c new file mode 100644 index 0000000000..802a73563d --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.c @@ -0,0 +1,91 @@ +#include <string.h> +#include "ge.h" +#include "crypto_additions.h" +#include "zeroize.h" +#include "vxeddsa.h" +#include "crypto_verify_32.h" + +int vxed25519_sign(unsigned char* signature_out, + const unsigned char* curve25519_privkey, + const unsigned char* msg, const unsigned long msg_len, + const unsigned char* random) +{ + unsigned char a[32], aneg[32]; + unsigned char A[32]; + ge_p3 Bv, ed_pubkey_point; + unsigned char sigbuf[MAX_MSG_LEN + 160]; /* working buffer */ + unsigned char sign_bit = 0; + + if (msg_len > MAX_MSG_LEN) { + memset(signature_out, 0, 96); + return -1; + } + /* Convert the Curve25519 privkey to an Ed25519 public key */ + ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey); + ge_p3_tobytes(A, &ed_pubkey_point); + + /* Force Edwards sign bit to zero */ + sign_bit = (A[31] & 0x80) >> 7; + memcpy(a, curve25519_privkey, 32); + sc_neg(aneg, a); + sc_cmov(a, aneg, sign_bit); + A[31] &= 0x7F; + + calculate_Bv_and_V(&Bv, signature_out, sigbuf, a, A, msg, msg_len); + + /* Perform an Ed25519 signature with explicit private key */ + crypto_vsign_modified(sigbuf, msg, msg_len, a, A, random, &Bv, signature_out /*V*/); + memmove(signature_out+32, sigbuf, 64); + + zeroize(a, 32); + zeroize(aneg, 32); + return 0; +} + +int vxed25519_verify(unsigned char* vrf_out, + const unsigned char* signature, + const unsigned char* curve25519_pubkey, + const unsigned char* msg, const unsigned long msg_len) +{ + fe u; + fe y; + unsigned char ed_pubkey[32]; + unsigned char strict[32]; + unsigned char verifybuf[MAX_MSG_LEN + 160]; /* working buffer */ + unsigned char verifybuf2[MAX_MSG_LEN + 160]; /* working buffer #2 ?? !!! */ + ge_p3 Bv; + + if (msg_len > MAX_MSG_LEN) { + return -1; + } + + /* Convert the Curve25519 public key (u) into an Ed25519 public key. + + y = (u - 1) / (u + 1) + + NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp + */ + fe_frombytes(u, curve25519_pubkey); + fe_tobytes(strict, u); + if (crypto_verify_32(strict, curve25519_pubkey) != 0) + return 0; + fe_montx_to_edy(y, u); + fe_tobytes(ed_pubkey, y); + + calculate_Bv(&Bv, verifybuf, ed_pubkey, msg, msg_len); + + memmove(verifybuf, signature, 96); + memmove(verifybuf+96, msg, msg_len); + + /* Then perform a signature verification, return 0 on success */ + /* The below call has a strange API: */ + /* verifybuf = V || h || s || message */ + /* verifybuf2 = used as buffer, gets the VRF output if success */ + if (crypto_vsign_open_modified(verifybuf2, verifybuf, 96 + msg_len, ed_pubkey, &Bv) == 0) { + memmove(vrf_out, verifybuf2, 32); + return 0; + } else { + memset(vrf_out, 0, 32); + return -1; + } +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.h b/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.h new file mode 100644 index 0000000000..4e48844170 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.h @@ -0,0 +1,18 @@ + +#ifndef __VXEDDSA_H__ +#define __VXEDDSA_H__ + +/* returns 0 on success */ +int vxed25519_sign(unsigned char* signature_out, /* 96 bytes */ + const unsigned char* curve25519_privkey, /* 32 bytes */ + const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */ + const unsigned char* random); /* 64 bytes */ + +/* returns 0 on success */ +int vxed25519_verify(unsigned char* vrf_out, /* 32 bytes */ + const unsigned char* signature, /* 96 bytes */ + const unsigned char* curve25519_pubkey, /* 32 bytes */ + const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */ + + +#endif diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.c b/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.c new file mode 100644 index 0000000000..ee2964a0d5 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.c @@ -0,0 +1,82 @@ +#include <string.h> +#include "ge.h" +#include "crypto_additions.h" +#include "zeroize.h" +#include "xeddsa.h" +#include "crypto_verify_32.h" + +int xed25519_sign(unsigned char* signature_out, + const unsigned char* curve25519_privkey, + const unsigned char* msg, const unsigned long msg_len, + const unsigned char* random) +{ + unsigned char a[32], aneg[32]; + unsigned char A[32]; + ge_p3 ed_pubkey_point; + unsigned char *sigbuf; /* working buffer */ + unsigned char sign_bit = 0; + + if ((sigbuf = malloc(msg_len + 128)) == 0) { + memset(signature_out, 0, 64); + return -1; + } + + /* Convert the Curve25519 privkey to an Ed25519 public key */ + ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey); + ge_p3_tobytes(A, &ed_pubkey_point); + + /* Force Edwards sign bit to zero */ + sign_bit = (A[31] & 0x80) >> 7; + memcpy(a, curve25519_privkey, 32); + sc_neg(aneg, a); + sc_cmov(a, aneg, sign_bit); + A[31] &= 0x7F; + + /* Perform an Ed25519 signature with explicit private key */ + crypto_sign_modified(sigbuf, msg, msg_len, a, A, random); + memmove(signature_out, sigbuf, 64); + + zeroize(a, 32); + zeroize(aneg, 32); + free(sigbuf); + return 0; +} + +int xed25519_verify(const unsigned char* signature, + const unsigned char* curve25519_pubkey, + const unsigned char* msg, const unsigned long msg_len) +{ + fe u; + fe y; + unsigned char ed_pubkey[32]; + unsigned char strict[32]; + unsigned char verifybuf[MAX_MSG_LEN + 64]; /* working buffer */ + unsigned char verifybuf2[MAX_MSG_LEN + 64]; /* working buffer #2 */ + + if (msg_len > MAX_MSG_LEN) { + return -1; + } + + /* Convert the Curve25519 public key into an Ed25519 public key. + + y = (u - 1) / (u + 1) + + NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp + */ + fe_frombytes(u, curve25519_pubkey); + fe_tobytes(strict, u); + if (crypto_verify_32(strict, curve25519_pubkey) != 0) + return 0; + fe_montx_to_edy(y, u); + fe_tobytes(ed_pubkey, y); + + memmove(verifybuf, signature, 64); + memmove(verifybuf+64, msg, msg_len); + + /* Then perform a normal Ed25519 verification, return 0 on success */ + /* The below call has a strange API: */ + /* verifybuf = R || S || message */ + /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets + replaced with pubkey for hashing */ + return crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey); +} diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.h b/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.h new file mode 100644 index 0000000000..b86d7f0d9d --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.h @@ -0,0 +1,16 @@ + +#ifndef __XEDDSA_H__ +#define __XEDDSA_H__ + +/* returns 0 on success */ +int xed25519_sign(unsigned char* signature_out, /* 64 bytes */ + const unsigned char* curve25519_privkey, /* 32 bytes */ + const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */ + const unsigned char* random); /* 64 bytes */ + +/* returns 0 on success */ +int xed25519_verify(const unsigned char* signature, /* 64 bytes */ + const unsigned char* curve25519_pubkey, /* 32 bytes */ + const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */ + +#endif diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.c b/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.c index 37c1f708bc..187e725eb5 100644 --- a/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.c +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.c @@ -3,7 +3,6 @@ void zeroize(unsigned char* b, size_t len) { size_t count = 0; - unsigned long retval = 0; volatile unsigned char *p = b; for (count = 0; count < len; count++) @@ -13,5 +12,5 @@ void zeroize(unsigned char* b, size_t len) void zeroize_stack() { unsigned char m[ZEROIZE_STACK_SIZE]; - zeroize(m, sizeof m); + zeroize(m, ZEROIZE_STACK_SIZE); } diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.h b/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.h index 80fcffb768..0db68bb4c6 100644 --- a/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.h +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.h @@ -3,7 +3,7 @@ #include <stdlib.h> -#define ZEROIZE_STACK_SIZE 2048 +#define ZEROIZE_STACK_SIZE 1024 void zeroize(unsigned char* b, size_t len); diff --git a/libs/libaxolotl/src/curve25519/ed25519/fe_isnonzero.c b/libs/libaxolotl/src/curve25519/ed25519/fe_isnonzero.c index 47568001ce..0e087a783d 100644 --- a/libs/libaxolotl/src/curve25519/ed25519/fe_isnonzero.c +++ b/libs/libaxolotl/src/curve25519/ed25519/fe_isnonzero.c @@ -2,13 +2,22 @@ #include "crypto_verify_32.h" /* -return 1 if f == 0 +return nonzero if f == 0 return 0 if f != 0 Preconditions: |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ +/* TREVOR'S COMMENT + * + * I think the above comment is wrong. Instead: + * + * return 0 if f == 0 + * return -1 if f != 0 + * + * */ + static const unsigned char zero[32]; int fe_isnonzero(const fe f) diff --git a/libs/libaxolotl/src/curve25519/ed25519/main/main.c b/libs/libaxolotl/src/curve25519/ed25519/main/main.c index 5fbe39956d..a6ff569b9e 100644 --- a/libs/libaxolotl/src/curve25519/ed25519/main/main.c +++ b/libs/libaxolotl/src/curve25519/ed25519/main/main.c @@ -1,106 +1,13 @@ -#include <stdio.h> -#include <string.h> -#include "crypto_hash_sha512.h" -#include "curve_sigs.h" +#include "tests.h" -#define MSG_LEN 200 int main(int argc, char* argv[]) { - unsigned char privkey[32]; - unsigned char pubkey[32]; - unsigned char signature[64]; - unsigned char msg[MSG_LEN]; - unsigned char random[64]; + all_fast_tests(0); + curvesigs_slow_test(0, 10000); + xeddsa_slow_test(0, 10000); + xeddsa_to_curvesigs_slow_test(0, 10000); + vxeddsa_slow_test(0, 10000000); - /* Initialize pubkey, privkey, msg */ - memset(msg, 0, MSG_LEN); - memset(privkey, 0, 32); - memset(pubkey, 0, 32); - privkey[0] &= 248; - privkey[31] &= 63; - privkey[31] |= 64; - - privkey[8] = 189; /* just so there's some bits set */ - - - /* SHA512 test */ - unsigned char sha512_input[112] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; - unsigned char sha512_correct_output[64] = -{ -0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, -0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, -0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, -0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, -0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, -0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, -0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, -0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 -}; - unsigned char sha512_actual_output[64]; - - crypto_hash_sha512(sha512_actual_output, sha512_input, sizeof(sha512_input)); - if (memcmp(sha512_actual_output, sha512_correct_output, 64) != 0) - printf("SHA512 bad #1\n"); - else - printf("SHA512 good #1\n"); - - sha512_input[111] ^= 1; - - crypto_hash_sha512(sha512_actual_output, sha512_input, sizeof(sha512_input)); - if (memcmp(sha512_actual_output, sha512_correct_output, 64) != 0) - printf("SHA512 good #2\n"); - else - printf("SHA512 bad #2\n"); - - /* Signature test */ - curve25519_keygen(pubkey, privkey); - - curve25519_sign(signature, privkey, msg, MSG_LEN, random); - - if (curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0) - printf("Signature good #1\n"); - else - printf("Signature bad #1\n"); - - signature[0] ^= 1; - - if (curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0) - printf("Signature bad #2\n"); - else - printf("Signature good #2\n"); - - - printf("Random testing...\n"); - for (int count = 0; count < 10000; count++) { - unsigned char b[64]; - crypto_hash_sha512(b, privkey, 32); - memmove(privkey, b, 32); - crypto_hash_sha512(b, privkey, 32); - memmove(random, b, 64); - - privkey[0] &= 248; - privkey[31] &= 63; - privkey[31] |= 64; - - curve25519_keygen(pubkey, privkey); - - curve25519_sign(signature, privkey, msg, MSG_LEN, random); - - if (curve25519_verify(signature, pubkey, msg, MSG_LEN) != 0) { - printf("failure #1 %d\n", count); - return -1; - } - - if (b[63] & 1) - signature[count % 64] ^= 1; - else - msg[count % MSG_LEN] ^= 1; - if (curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0) { - printf("failure #2 %d\n", count); - return -1; - } - } - printf("OK\n"); - return 1; + return 0; } diff --git a/libs/libaxolotl/src/curve25519/ed25519/tests/tests.c b/libs/libaxolotl/src/curve25519/ed25519/tests/tests.c new file mode 100644 index 0000000000..79adae5d16 --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/tests/tests.c @@ -0,0 +1,658 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "crypto_hash_sha512.h" +#include "keygen.h" +#include "curve_sigs.h" +#include "xeddsa.h" +#include "vxeddsa.h" +#include "crypto_additions.h" +#include "ge.h" +#include "utility.h" +#include "tests.h" +#include <assert.h> + + +#define ERROR(...) do {if (!silent) { printf(__VA_ARGS__); abort(); } else return -1; } while (0) +#define INFO(...) do {if (!silent) printf(__VA_ARGS__);} while (0) + +#define TEST(msg, cond) \ + do { \ + if ((cond)) { \ + INFO("%s good\n", msg); \ + } \ + else { \ + ERROR("%s BAD!!!\n", msg); \ + } \ + } while (0) + + +int sha512_fast_test(int silent) +{ + unsigned char sha512_input[112] = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; + unsigned char sha512_correct_output[64] = + { + 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, + 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, + 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, + 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, + 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, + 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, + 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, + 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 + }; + unsigned char sha512_actual_output[64]; + + crypto_hash_sha512(sha512_actual_output, sha512_input, sizeof(sha512_input)); + TEST("SHA512 #1", memcmp(sha512_actual_output, sha512_correct_output, 64) == 0); + + sha512_input[111] ^= 1; + + crypto_hash_sha512(sha512_actual_output, sha512_input, sizeof(sha512_input)); + TEST("SHA512 #2", memcmp(sha512_actual_output, sha512_correct_output, 64) != 0); + + return 0; +} + +int elligator_fast_test(int silent) +{ + unsigned char elligator_correct_output[32] = + { + 0x5f, 0x35, 0x20, 0x00, 0x1c, 0x6c, 0x99, 0x36, + 0xa3, 0x12, 0x06, 0xaf, 0xe7, 0xc7, 0xac, 0x22, + 0x4e, 0x88, 0x61, 0x61, 0x9b, 0xf9, 0x88, 0x72, + 0x44, 0x49, 0x15, 0x89, 0x9d, 0x95, 0xf4, 0x6e + }; + + unsigned char hashtopoint_correct_output1[32] = + { + 0xce, 0x89, 0x9f, 0xb2, 0x8f, 0xf7, 0x20, 0x91, + 0x5e, 0x14, 0xf5, 0xb7, 0x99, 0x08, 0xab, 0x17, + 0xaa, 0x2e, 0xe2, 0x45, 0xb4, 0xfc, 0x2b, 0xf6, + 0x06, 0x36, 0x29, 0x40, 0xed, 0x7d, 0xe7, 0xed + }; + + unsigned char hashtopoint_correct_output2[32] = + { + 0xa0, 0x35, 0xbb, 0xa9, 0x4d, 0x30, 0x55, 0x33, + 0x0d, 0xce, 0xc2, 0x7f, 0x83, 0xde, 0x79, 0xd0, + 0x89, 0x67, 0x72, 0x4c, 0x07, 0x8d, 0x68, 0x9d, + 0x61, 0x52, 0x1d, 0xf9, 0x2c, 0x5c, 0xba, 0x77 + }; + + unsigned char calculatev_correct_output[32] = + { + 0x1b, 0x77, 0xb5, 0xa0, 0x44, 0x84, 0x7e, 0xb9, + 0x23, 0xd7, 0x93, 0x18, 0xce, 0xc2, 0xc5, 0xe2, + 0x84, 0xd5, 0x79, 0x6f, 0x65, 0x63, 0x1b, 0x60, + 0x9b, 0xf1, 0xf8, 0xce, 0x88, 0x0b, 0x50, 0x9c, + }; + + int count; + fe in, out; + unsigned char bytes[32]; + fe_0(in); + fe_0(out); + for (count = 0; count < 32; count++) { + bytes[count] = count; + } + fe_frombytes(in, bytes); + elligator(out, in); + fe_tobytes(bytes, out); + TEST("Elligator vector", memcmp(bytes, elligator_correct_output, 32) == 0); + + /* Elligator(0) == 0 test */ + fe_0(in); + elligator(out, in); + TEST("Elligator(0) == 0", memcmp(in, out, 32) == 0); + + /* ge_montx_to_p3(0) -> order2 point test */ + fe one, negone, zero; + fe_1(one); + fe_0(zero); + fe_sub(negone, zero, one); + ge_p3 p3; + ge_montx_to_p3(&p3, zero, 0); + TEST("ge_montx_to_p3(0) == order 2 point", + fe_isequal(p3.X, zero) && + fe_isequal(p3.Y, negone) && + fe_isequal(p3.Z, one) && + fe_isequal(p3.T, zero)); + + /* Hash to point vector test */ + unsigned char htp[32]; + + for (count=0; count < 32; count++) { + htp[count] = count; + } + + hash_to_point(&p3, htp, 32); + ge_p3_tobytes(htp, &p3); + TEST("hash_to_point #1", memcmp(htp, hashtopoint_correct_output1, 32) == 0); + + for (count=0; count < 32; count++) { + htp[count] = count+1; + } + + hash_to_point(&p3, htp, 32); + ge_p3_tobytes(htp, &p3); + TEST("hash_to_point #2", memcmp(htp, hashtopoint_correct_output2, 32) == 0); + + /* calculate_U vector test */ + ge_p3 Bv; + unsigned char V[32]; + unsigned char Vbuf[200]; + unsigned char a[32]; + unsigned char A[32]; + unsigned char Vmsg[3]; + Vmsg[0] = 0; + Vmsg[1] = 1; + Vmsg[2] = 2; + for (count=0; count < 32; count++) { + a[count] = 8 + count; + A[count] = 9 + count; + } + sc_clamp(a); + calculate_Bv_and_V(&Bv, V, Vbuf, a, A, Vmsg, 3); + TEST("calculate_Bv_and_V vector", memcmp(V, calculatev_correct_output, 32) == 0); + return 0; +} + +int curvesigs_fast_test(int silent) +{ + unsigned char signature_correct[64] = { + 0xcf, 0x87, 0x3d, 0x03, 0x79, 0xac, 0x20, 0xe8, + 0x89, 0x3e, 0x55, 0x67, 0xee, 0x0f, 0x89, 0x51, + 0xf8, 0xdb, 0x84, 0x0d, 0x26, 0xb2, 0x43, 0xb4, + 0x63, 0x52, 0x66, 0x89, 0xd0, 0x1c, 0xa7, 0x18, + 0xac, 0x18, 0x9f, 0xb1, 0x67, 0x85, 0x74, 0xeb, + 0xdd, 0xe5, 0x69, 0x33, 0x06, 0x59, 0x44, 0x8b, + 0x0b, 0xd6, 0xc1, 0x97, 0x3f, 0x7d, 0x78, 0x0a, + 0xb3, 0x95, 0x18, 0x62, 0x68, 0x03, 0xd7, 0x82, + }; + const int MSG_LEN = 200; + unsigned char privkey[32]; + unsigned char pubkey[32]; + unsigned char signature[64]; + unsigned char msg[MSG_LEN]; + unsigned char random[64]; + + memset(privkey, 0, 32); + memset(pubkey, 0, 32); + memset(signature, 0, 64); + memset(msg, 0, MSG_LEN); + memset(random, 0, 64); + + privkey[8] = 189; /* just so there's some bits set */ + sc_clamp(privkey); + + /* Signature vector test */ + curve25519_keygen(pubkey, privkey); + + curve25519_sign(signature, privkey, msg, MSG_LEN, random); + + TEST("Curvesig sign", memcmp(signature, signature_correct, 64) == 0); + TEST("Curvesig verify #1", curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0); + signature[0] ^= 1; + TEST("Curvesig verify #2", curve25519_verify(signature, pubkey, msg, MSG_LEN) != 0); + return 0; +} + +int xeddsa_fast_test(int silent) +{ + unsigned char signature_correct[64] = { + 0x11, 0xc7, 0xf3, 0xe6, 0xc4, 0xdf, 0x9e, 0x8a, + 0x51, 0x50, 0xe1, 0xdb, 0x3b, 0x30, 0xf9, 0x2d, + 0xe3, 0xa3, 0xb3, 0xaa, 0x43, 0x86, 0x56, 0x54, + 0x5f, 0xa7, 0x39, 0x0f, 0x4b, 0xcc, 0x7b, 0xb2, + 0x6c, 0x43, 0x1d, 0x9e, 0x90, 0x64, 0x3e, 0x4f, + 0x0e, 0xaa, 0x0e, 0x9c, 0x55, 0x77, 0x66, 0xfa, + 0x69, 0xad, 0xa5, 0x76, 0xd6, 0x3d, 0xca, 0xf2, + 0xac, 0x32, 0x6c, 0x11, 0xd0, 0xb9, 0x77, 0x02, + }; + const int MSG_LEN = 200; + unsigned char privkey[32]; + unsigned char pubkey[32]; + unsigned char signature[64]; + unsigned char msg[MSG_LEN]; + unsigned char random[64]; + + memset(privkey, 0, 32); + memset(pubkey, 0, 32); + memset(signature, 0, 64); + memset(msg, 0, MSG_LEN); + memset(random, 0, 64); + + privkey[8] = 189; /* just so there's some bits set */ + sc_clamp(privkey); + + /* Signature vector test */ + curve25519_keygen(pubkey, privkey); + + xed25519_sign(signature, privkey, msg, MSG_LEN, random); + TEST("XEdDSA sign", memcmp(signature, signature_correct, 64) == 0); + TEST("XEdDSA verify #1", xed25519_verify(signature, pubkey, msg, MSG_LEN) == 0); + signature[0] ^= 1; + TEST("XEdDSA verify #2", xed25519_verify(signature, pubkey, msg, MSG_LEN) != 0); + return 0; +} + +int vxeddsa_fast_test(int silent) +{ + unsigned char signature_correct[96] = { + 0x23, 0xc6, 0xe5, 0x93, 0x3f, 0xcd, 0x56, 0x47, + 0x7a, 0x86, 0xc9, 0x9b, 0x76, 0x2c, 0xb5, 0x24, + 0xc3, 0xd6, 0x05, 0x55, 0x38, 0x83, 0x4d, 0x4f, + 0x8d, 0xb8, 0xf0, 0x31, 0x07, 0xec, 0xeb, 0xa0, + 0xa0, 0x01, 0x50, 0xb8, 0x4c, 0xbb, 0x8c, 0xcd, + 0x23, 0xdc, 0x65, 0xfd, 0x0e, 0x81, 0xb2, 0x86, + 0x06, 0xa5, 0x6b, 0x0c, 0x4f, 0x53, 0x6d, 0xc8, + 0x8b, 0x8d, 0xc9, 0x04, 0x6e, 0x4a, 0xeb, 0x08, + 0xce, 0x08, 0x71, 0xfc, 0xc7, 0x00, 0x09, 0xa4, + 0xd6, 0xc0, 0xfd, 0x2d, 0x1a, 0xe5, 0xb6, 0xc0, + 0x7c, 0xc7, 0x22, 0x3b, 0x69, 0x59, 0xa8, 0x26, + 0x2b, 0x57, 0x78, 0xd5, 0x46, 0x0e, 0x0f, 0x05, + }; + const int MSG_LEN = 200; + unsigned char privkey[32]; + unsigned char pubkey[32]; + unsigned char signature[96]; + unsigned char msg[MSG_LEN]; + unsigned char random[64]; + unsigned char vrf_out[32]; + unsigned char vrf_outprev[32]; + + memset(privkey, 0, 32); + memset(pubkey, 0, 32); + memset(signature, 0, 96); + memset(msg, 0, MSG_LEN); + memset(random, 0, 64); + + privkey[8] = 189; /* just so there's some bits set */ + sc_clamp(privkey); + + /* Signature vector test */ + curve25519_keygen(pubkey, privkey); + + vxed25519_sign(signature, privkey, msg, MSG_LEN, random); + + TEST("VXEdDSA sign", memcmp(signature, signature_correct, 96) == 0); + TEST("VXEdDSA verify #1", vxed25519_verify(vrf_out, signature, pubkey, msg, MSG_LEN) == 0); + memcpy(vrf_outprev, vrf_out, 32); + signature[0] ^= 1; + TEST("VXEdDSA verify #2", vxed25519_verify(vrf_out, signature, pubkey, msg, MSG_LEN) != 0); + + /* Test U */ + unsigned char sigprev[96]; + memcpy(sigprev, signature, 96); + sigprev[0] ^= 1; /* undo prev disturbance */ + + random[0] ^= 1; + vxed25519_sign(signature, privkey, msg, MSG_LEN, random); + TEST("VXEdDSA verify #3", vxed25519_verify(vrf_out, signature, pubkey, msg, MSG_LEN) == 0); + + TEST("VXEdDSA VRF value unchanged", memcmp(vrf_out, vrf_outprev, 32) == 0); + TEST("VXEdDSA (h, s) changed", memcmp(signature+32, sigprev+32, 64) != 0); + return 0; +} + +int curvesigs_slow_test(int silent, int iterations) +{ + + unsigned char signature_10k_correct[64] = { + 0xfc, 0xba, 0x55, 0xc4, 0x85, 0x4a, 0x42, 0x25, + 0x19, 0xab, 0x08, 0x8d, 0xfe, 0xb5, 0x13, 0xb6, + 0x0d, 0x24, 0xbb, 0x16, 0x27, 0x55, 0x71, 0x48, + 0xdd, 0x20, 0xb1, 0xcd, 0x2a, 0xd6, 0x7e, 0x35, + 0xef, 0x33, 0x4c, 0x7b, 0x6d, 0x94, 0x6f, 0x52, + 0xec, 0x43, 0xd7, 0xe6, 0x35, 0x24, 0xcd, 0x5b, + 0x5d, 0xdc, 0xb2, 0x32, 0xc6, 0x22, 0x53, 0xf3, + 0x38, 0x02, 0xf8, 0x28, 0x28, 0xc5, 0x65, 0x05, + }; + + int count; + const int MSG_LEN = 200; + unsigned char privkey[32]; + unsigned char pubkey[32]; + unsigned char signature[64]; + unsigned char msg[MSG_LEN]; + unsigned char random[64]; + + memset(privkey, 0, 32); + memset(pubkey, 0, 32); + memset(signature, 0, 64); + memset(msg, 0, MSG_LEN); + memset(random, 0, 64); + + /* Signature random test */ + INFO("Pseudorandom curvesigs...\n"); + for (count = 1; count <= iterations; count++) { + unsigned char b[64]; + crypto_hash_sha512(b, signature, 64); + memmove(privkey, b, 32); + crypto_hash_sha512(b, privkey, 32); + memmove(random, b, 64); + + sc_clamp(privkey); + curve25519_keygen(pubkey, privkey); + + curve25519_sign(signature, privkey, msg, MSG_LEN, random); + + if (curve25519_verify(signature, pubkey, msg, MSG_LEN) != 0) + ERROR("Curvesig verify failure #1 %d\n", count); + + if (b[63] & 1) + signature[count % 64] ^= 1; + else + msg[count % MSG_LEN] ^= 1; + if (curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0) + ERROR("Curvesig verify failure #2 %d\n", count); + + if (count == 10000) { + if (memcmp(signature, signature_10k_correct, 64) != 0) + ERROR("Curvesig signature 10K doesn't match %d\n", count); + } + if (count == 100000) + print_bytes("100K curvesigs", signature, 64); + if (count == 1000000) + print_bytes("1M curvesigs", signature, 64); + if (count == 10000000) + print_bytes("10M curvesigs", signature, 64); + } + INFO("good\n"); + return 0; +} + +int xeddsa_slow_test(int silent, int iterations) +{ + + unsigned char signature_10k_correct[64] = { + 0x15, 0x29, 0x03, 0x38, 0x66, 0x16, 0xcd, 0x26, + 0xbb, 0x3e, 0xec, 0xe2, 0x9f, 0x72, 0xa2, 0x5c, + 0x7d, 0x05, 0xc9, 0xcb, 0x84, 0x3f, 0x92, 0x96, + 0xb3, 0xfb, 0xb9, 0xdd, 0xd6, 0xed, 0x99, 0x04, + 0xc1, 0xa8, 0x02, 0x16, 0xcf, 0x49, 0x3f, 0xf1, + 0xbe, 0x69, 0xf9, 0xf1, 0xcc, 0x16, 0xd7, 0xdc, + 0x6e, 0xd3, 0x78, 0xaa, 0x04, 0xeb, 0x71, 0x51, + 0x9d, 0xe8, 0x7a, 0x5b, 0xd8, 0x49, 0x7b, 0x05, + }; + + int count; + const int MSG_LEN = 200; + unsigned char privkey[32]; + unsigned char pubkey[32]; + unsigned char signature[96]; + unsigned char msg[MSG_LEN]; + unsigned char random[64]; + + memset(privkey, 0, 32); + memset(pubkey, 0, 32); + memset(signature, 1, 64); + memset(msg, 0, MSG_LEN); + memset(random, 0, 64); + + /* Signature random test */ + INFO("Pseudorandom XEdDSA...\n"); + for (count = 1; count <= iterations; count++) { + unsigned char b[64]; + crypto_hash_sha512(b, signature, 64); + memmove(privkey, b, 32); + crypto_hash_sha512(b, privkey, 32); + memmove(random, b, 64); + + sc_clamp(privkey); + curve25519_keygen(pubkey, privkey); + + xed25519_sign(signature, privkey, msg, MSG_LEN, random); + + if (xed25519_verify(signature, pubkey, msg, MSG_LEN) != 0) + ERROR("XEdDSA verify failure #1 %d\n", count); + + if (b[63] & 1) + signature[count % 64] ^= 1; + else + msg[count % MSG_LEN] ^= 1; + if (xed25519_verify(signature, pubkey, msg, MSG_LEN) == 0) + ERROR("XEdDSA verify failure #2 %d\n", count); + + if (count == 10000) { + if (memcmp(signature, signature_10k_correct, 64) != 0) + ERROR("XEDSA signature 10K doesn't match %d\n", count); + } + if (count == 100000) + print_bytes("100K XEdDSA", signature, 64); + if (count == 1000000) + print_bytes("1M XEdDSA", signature, 64); + if (count == 10000000) + print_bytes("10M XEdDSA", signature, 64); + } + INFO("good\n"); + return 0; +} + +int xeddsa_to_curvesigs_slow_test(int silent, int iterations) +{ + + unsigned char signature_10k_correct[64] = { + 0x33, 0x50, 0xa8, 0x68, 0xcd, 0x9e, 0x74, 0x99, + 0xa3, 0x5c, 0x33, 0x75, 0x2b, 0x22, 0x03, 0xf8, + 0xb5, 0x0f, 0xea, 0x8c, 0x33, 0x1c, 0x68, 0x8b, + 0xbb, 0xf3, 0x31, 0xcf, 0x7c, 0x42, 0x37, 0x35, + 0xa0, 0x0e, 0x15, 0xb8, 0x5d, 0x2b, 0xe1, 0xa2, + 0x03, 0x77, 0x94, 0x3d, 0x13, 0x5c, 0xd4, 0x9b, + 0x6a, 0x31, 0xf4, 0xdc, 0xfe, 0x24, 0xad, 0x54, + 0xeb, 0xd2, 0x98, 0x47, 0xf1, 0xcc, 0xbf, 0x0d + + }; + + int count; + const int MSG_LEN = 200; + unsigned char privkey[32]; + unsigned char pubkey[32]; + unsigned char signature[96]; + unsigned char msg[MSG_LEN]; + unsigned char random[64]; + + memset(privkey, 0, 32); + memset(pubkey, 0, 32); + memset(signature, 2, 64); + memset(msg, 0, MSG_LEN); + memset(random, 0, 64); + + /* Signature random test */ + INFO("Pseudorandom XEdDSA/Curvesigs...\n"); + for (count = 1; count <= iterations; count++) { + unsigned char b[64]; + crypto_hash_sha512(b, signature, 64); + memmove(privkey, b, 32); + crypto_hash_sha512(b, privkey, 32); + memmove(random, b, 64); + + sc_clamp(privkey); + curve25519_keygen(pubkey, privkey); + + xed25519_sign(signature, privkey, msg, MSG_LEN, random); + + if (curve25519_verify(signature, pubkey, msg, MSG_LEN) != 0) + ERROR("XEdDSA/Curvesigs verify failure #1 %d\n", count); + + if (b[63] & 1) + signature[count % 64] ^= 1; + else + msg[count % MSG_LEN] ^= 1; + if (curve25519_verify(signature, pubkey, msg, MSG_LEN) == 0) + ERROR("XEdDSA/Curvesigs verify failure #2 %d\n", count); + + if (count == 10000) { + if (memcmp(signature, signature_10k_correct, 64) != 0) + ERROR("XEdDSA/Curvesigs signature 10K doesn't match %d\n", count); + } + if (count == 100000) + print_bytes("100K XEdDSA/C", signature, 64); + if (count == 1000000) + print_bytes("1M XEdDSA/C", signature, 64); + if (count == 10000000) + print_bytes("10M XEdDSA/C", signature, 64); + } + INFO("good\n"); + return 0; +} + +int vxeddsa_slow_test(int silent, int iterations) +{ + + unsigned char signature_10k_correct[96] = { + 0xa1, 0x96, 0x96, 0xe5, 0x87, 0x3f, 0x6e, 0x5c, + 0x2e, 0xd3, 0x73, 0xab, 0x04, 0x0c, 0x1f, 0x26, + 0x3c, 0xca, 0x52, 0xc4, 0x7e, 0x49, 0xaa, 0xce, + 0xb5, 0xd6, 0xa2, 0x29, 0x46, 0x3f, 0x1b, 0x54, + 0x45, 0x94, 0x9b, 0x6c, 0x27, 0xf9, 0x2a, 0xed, + 0x17, 0xa4, 0x72, 0xbf, 0x35, 0x37, 0xc1, 0x90, + 0xac, 0xb3, 0xfd, 0x2d, 0xf1, 0x01, 0x05, 0xbe, + 0x56, 0x5c, 0xaf, 0x63, 0x65, 0xad, 0x38, 0x04, + 0x70, 0x53, 0xdf, 0x2b, 0xc1, 0x45, 0xc8, 0xee, + 0x02, 0x0d, 0x2b, 0x22, 0x23, 0x7a, 0xbf, 0xfa, + 0x43, 0x31, 0xb3, 0xac, 0x26, 0xd9, 0x76, 0xfc, + 0xfe, 0x30, 0xa1, 0x7c, 0xce, 0x10, 0x67, 0x0e, + }; + + unsigned char signature_100k_correct[96] = { + 0xc9, 0x11, 0x2b, 0x55, 0xfa, 0xc4, 0xb2, 0xfe, + 0x00, 0x7d, 0xf6, 0x45, 0xcb, 0xd2, 0x73, 0xc9, + 0x43, 0xba, 0x20, 0xf6, 0x9c, 0x18, 0x84, 0xef, + 0x6c, 0x65, 0x7a, 0xdb, 0x49, 0xfc, 0x1e, 0xbe, + 0x31, 0xb3, 0xe6, 0xa4, 0x68, 0x2f, 0xd0, 0x30, + 0x81, 0xfc, 0x0d, 0xcd, 0x2d, 0x00, 0xab, 0xae, + 0x9f, 0x08, 0xf0, 0x99, 0xff, 0x9f, 0xdc, 0x2d, + 0x68, 0xd6, 0xe7, 0xe8, 0x44, 0x2a, 0x5b, 0x0e, + 0x48, 0x67, 0xe2, 0x41, 0x4a, 0xd9, 0x0c, 0x2a, + 0x2b, 0x4e, 0x66, 0x09, 0x87, 0xa0, 0x6b, 0x3b, + 0xd1, 0xd9, 0xa3, 0xe3, 0xa5, 0x69, 0xed, 0xc1, + 0x42, 0x03, 0x93, 0x0d, 0xbc, 0x7e, 0xe9, 0x08, + }; + + unsigned char signature_1m_correct[96] = { + 0xf8, 0xb1, 0x20, 0xf2, 0x1e, 0x5c, 0xbf, 0x5f, + 0xea, 0x07, 0xcb, 0xb5, 0x77, 0xb8, 0x03, 0xbc, + 0xcb, 0x6d, 0xf1, 0xc1, 0xa5, 0x03, 0x05, 0x7b, + 0x01, 0x63, 0x9b, 0xf9, 0xed, 0x3e, 0x57, 0x47, + 0xd2, 0x5b, 0xf4, 0x7e, 0x7c, 0x45, 0xce, 0xfc, + 0x06, 0xb3, 0xf4, 0x05, 0x81, 0x9f, 0x53, 0xb0, + 0x18, 0xe3, 0xfa, 0xcb, 0xb2, 0x52, 0x3e, 0x57, + 0xcb, 0x34, 0xcc, 0x81, 0x60, 0xb9, 0x0b, 0x04, + 0x07, 0x79, 0xc0, 0x53, 0xad, 0xc4, 0x4b, 0xd0, + 0xb5, 0x7d, 0x95, 0x4e, 0xbe, 0xa5, 0x75, 0x0c, + 0xd4, 0xbf, 0xa7, 0xc0, 0xcf, 0xba, 0xe7, 0x7c, + 0xe2, 0x90, 0xef, 0x61, 0xa9, 0x29, 0x66, 0x0d, + }; + + unsigned char signature_10m_correct[96] = { + 0xf5, 0xa4, 0xbc, 0xec, 0xc3, 0x3d, 0xd0, 0x43, + 0xd2, 0x81, 0x27, 0x9e, 0xf0, 0x4c, 0xbe, 0xf3, + 0x77, 0x01, 0x56, 0x41, 0x0e, 0xff, 0x0c, 0xb9, + 0x66, 0xec, 0x4d, 0xe0, 0xb7, 0x25, 0x63, 0x6b, + 0x5c, 0x08, 0x39, 0x80, 0x4e, 0x37, 0x1b, 0x2c, + 0x46, 0x6f, 0x86, 0x99, 0x1c, 0x4e, 0x31, 0x60, + 0xdb, 0x4c, 0xfe, 0xc5, 0xa2, 0x4d, 0x71, 0x2b, + 0xd6, 0xd0, 0xc3, 0x98, 0x88, 0xdb, 0x0e, 0x0c, + 0x68, 0x4a, 0xd3, 0xc7, 0x56, 0xac, 0x8d, 0x95, + 0x7b, 0xbd, 0x99, 0x50, 0xe8, 0xd3, 0xea, 0xf3, + 0x7b, 0x26, 0xf2, 0xa2, 0x2b, 0x02, 0x58, 0xca, + 0xbd, 0x2c, 0x2b, 0xf7, 0x77, 0x58, 0xfe, 0x09, + }; + + int count; + const int MSG_LEN = 200; + unsigned char privkey[32]; + unsigned char pubkey[32]; + unsigned char signature[96]; + unsigned char msg[MSG_LEN]; + unsigned char random[64]; + unsigned char vrf_out[32]; + + memset(privkey, 0, 32); + memset(pubkey, 0, 32); + memset(signature, 3, 96); + memset(msg, 0, MSG_LEN); + memset(random, 0, 64); + + INFO("Pseudorandom VXEdDSA...\n"); + for (count = 1; count <= iterations; count++) { + unsigned char b[64]; + crypto_hash_sha512(b, signature, 96); + memmove(privkey, b, 32); + crypto_hash_sha512(b, privkey, 32); + memmove(random, b, 64); + + sc_clamp(privkey); + curve25519_keygen(pubkey, privkey); + + vxed25519_sign(signature, privkey, msg, MSG_LEN, random); + + if (vxed25519_verify(vrf_out, signature, pubkey, msg, MSG_LEN) != 0) + ERROR("VXEdDSA verify failure #1 %d\n", count); + + if (b[63] & 1) + signature[count % 96] ^= 1; + else + msg[count % MSG_LEN] ^= 1; + + if (vxed25519_verify(vrf_out, signature, pubkey, msg, MSG_LEN) == 0) + ERROR("VXEdDSA verify failure #2 %d\n", count); + + if (count == 10000) + print_bytes("10K VXEdDSA", signature, 96); + if (count == 100000) + print_bytes("100K VXEdDSA", signature, 96); + if (count == 1000000) + print_bytes("1M VXEdDSA", signature, 96); + if (count == 10000000) + print_bytes("10M VXEdDSA", signature, 96); + if (count == 100000000) + print_bytes("100M VXEdDSA", signature, 96); + + if (count == 10000) { + if (memcmp(signature, signature_10k_correct, 96) != 0) + ERROR("VXEDDSA 10K doesn't match %d\n", count); + } + if (count == 100000) { + if (memcmp(signature, signature_100k_correct, 96) != 0) + ERROR("VXEDDSA 100K doesn't match %d\n", count); + } + if (count == 1000000) { + if (memcmp(signature, signature_1m_correct, 96) != 0) + ERROR("VXEDDSA 1m doesn't match %d\n", count); + } + if (count == 10000000) { + if (memcmp(signature, signature_10m_correct, 96) != 0) + ERROR("VXEDDSA 10m doesn't match %d\n", count); + } + /* + if (count == 100000000) { + if (memcmp(signature, signature_100m_correct, 96) != 0) + ERROR("VXEDDSA 100m doesn't match %d\n", count); + } + */ + } + INFO("good\n"); + return 0; +} + +int all_fast_tests(int silent) +{ + int result; + if ((result = sha512_fast_test(silent)) != 0) + return result; + if ((result = elligator_fast_test(silent)) != 0) + return result; + if ((result = curvesigs_fast_test(silent)) != 0) + return result; + if ((result = xeddsa_fast_test(silent)) != 0) + return result; + if ((result = vxeddsa_fast_test(silent)) != 0) + return result; + + return 0; +} + diff --git a/libs/libaxolotl/src/curve25519/ed25519/tests/tests.h b/libs/libaxolotl/src/curve25519/ed25519/tests/tests.h new file mode 100644 index 0000000000..1623268bde --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/tests/tests.h @@ -0,0 +1,22 @@ +#ifndef __TESTS_H__ +#define __TESTS_H__ + +/* silent = 0 : prints info+error messages to stdout, abort() on test failure + * silent = 1 : returns 0 for success, anything else for failure + * iterations : hardcoded known-good values are at 10000, so run at least this many + */ + +int sha512_fast_test(int silent); +int elligator_fast_test(int silent); +int curvesigs_fast_test(int silent); +int xeddsa_fast_test(int silent); +int vxeddsa_fast_test(int silent); + +int curvesigs_slow_test(int silent, int iterations); +int xeddsa_slow_test(int silent, int iterations); +int xeddsa_to_curvesigs_slow_test(int silent, int iterations); +int vxeddsa_slow_test(int silent, int iterations); + +int all_fast_tests(int silent); + +#endif diff --git a/libs/libaxolotl/src/device_consistency.c b/libs/libaxolotl/src/device_consistency.c new file mode 100644 index 0000000000..f01ed15363 --- /dev/null +++ b/libs/libaxolotl/src/device_consistency.c @@ -0,0 +1,646 @@ +#include "device_consistency.h" + +#include <assert.h> +#include <string.h> + +#include "signal_protocol_internal.h" +#include "curve.h" +#include "WhisperTextProtocol.pb-c.h" +#include "utarray.h" + +#define CODE_VERSION 0 + +struct device_consistency_signature +{ + signal_type_base base; + signal_buffer *signature; + signal_buffer *vrf_output; +}; + +struct device_consistency_commitment +{ + signal_type_base base; + uint32_t generation; + signal_buffer *serialized; +}; + +struct device_consistency_message +{ + signal_type_base base; + device_consistency_signature *signature; + uint32_t generation; + signal_buffer *serialized; +}; + +struct device_consistency_signature_list +{ + UT_array *values; +}; + +static int device_consistency_message_create(device_consistency_message **message); +static void device_consistency_signature_list_sort(device_consistency_signature_list *list); + +/*------------------------------------------------------------------------*/ + +int device_consistency_signature_create(device_consistency_signature **signature, + const uint8_t *signature_data, size_t signature_len, + const uint8_t *vrf_output_data, size_t vrf_output_len) +{ + int result = 0; + device_consistency_signature *result_signature = 0; + + result_signature = malloc(sizeof(device_consistency_signature)); + if(!result_signature) { + result = SG_ERR_NOMEM; + goto complete; + } + memset(result_signature, 0, sizeof(device_consistency_signature)); + SIGNAL_INIT(result_signature, device_consistency_signature_destroy); + + result_signature->signature = signal_buffer_create(signature_data, signature_len); + if(!result_signature->signature) { + result = SG_ERR_NOMEM; + goto complete; + } + + result_signature->vrf_output = signal_buffer_create(vrf_output_data, vrf_output_len); + if(!result_signature->vrf_output) { + result = SG_ERR_NOMEM; + goto complete; + } + +complete: + if(result >= 0) { + *signature = result_signature; + } + else { + SIGNAL_UNREF(result_signature); + } + return result; +} + +signal_buffer *device_consistency_signature_get_signature(const device_consistency_signature *signature) +{ + assert(signature); + return signature->signature; +} + +signal_buffer *device_consistency_signature_get_vrf_output(const device_consistency_signature *signature) +{ + assert(signature); + return signature->vrf_output; +} + +void device_consistency_signature_destroy(signal_type_base *type) +{ + device_consistency_signature *signature = (device_consistency_signature *)type; + signal_buffer_free(signature->signature); + signal_buffer_free(signature->vrf_output); + free(signature); +} + +/*------------------------------------------------------------------------*/ + +int device_consistency_commitment_create(device_consistency_commitment **commitment, + uint32_t generation, ec_public_key_list *identity_key_list, + signal_context *global_context) +{ + static const char version[] = "DeviceConsistencyCommitment_V0"; + int result = 0; + void *digest_context = 0; + device_consistency_commitment *result_commitment = 0; + ec_public_key_list *sorted_list = 0; + uint8_t gen_data[4]; + unsigned int list_size; + unsigned int i; + + result_commitment = malloc(sizeof(device_consistency_commitment)); + if(!result_commitment) { + result = SG_ERR_NOMEM; + goto complete; + } + memset(result_commitment, 0, sizeof(device_consistency_commitment)); + SIGNAL_INIT(result_commitment, device_consistency_commitment_destroy); + + sorted_list = ec_public_key_list_copy(identity_key_list); + if(!sorted_list) { + result = SG_ERR_NOMEM; + goto complete; + } + + ec_public_key_list_sort(sorted_list); + + result = signal_sha512_digest_init(global_context, &digest_context); + if(result < 0) { + goto complete; + } + + result = signal_sha512_digest_update(global_context, digest_context, + (uint8_t *)version, sizeof(version) - 1); + if(result < 0) { + goto complete; + } + + gen_data[3] = (uint8_t)(generation); + gen_data[2] = (uint8_t)(generation >> 8); + gen_data[1] = (uint8_t)(generation >> 16); + gen_data[0] = (uint8_t)(generation >> 24); + + result = signal_sha512_digest_update(global_context, digest_context, + gen_data, sizeof(gen_data)); + if(result < 0) { + goto complete; + } + + list_size = ec_public_key_list_size(sorted_list); + for(i = 0; i < list_size; i++) { + signal_buffer *key_buffer = 0; + ec_public_key *key = ec_public_key_list_at(sorted_list, i); + + result = ec_public_key_serialize(&key_buffer, key); + if(result < 0) { + goto complete; + } + + result = signal_sha512_digest_update(global_context, digest_context, + signal_buffer_data(key_buffer), signal_buffer_len(key_buffer)); + signal_buffer_free(key_buffer); + if(result < 0) { + goto complete; + } + } + + result_commitment->generation = generation; + result = signal_sha512_digest_final(global_context, digest_context, &result_commitment->serialized); + +complete: + if(sorted_list) { + ec_public_key_list_free(sorted_list); + } + if(digest_context) { + signal_sha512_digest_cleanup(global_context, digest_context); + } + if(result >= 0) { + *commitment = result_commitment; + } + else { + SIGNAL_UNREF(result_commitment); + } + return result; +} + +uint32_t device_consistency_commitment_get_generation(const device_consistency_commitment *commitment) +{ + assert(commitment); + return commitment->generation; +} + +signal_buffer *device_consistency_commitment_get_serialized(const device_consistency_commitment *commitment) +{ + assert(commitment); + return commitment->serialized; +} + +void device_consistency_commitment_destroy(signal_type_base *type) +{ + device_consistency_commitment *commitment = (device_consistency_commitment *)type; + signal_buffer_free(commitment->serialized); + free(commitment); +} + +/*------------------------------------------------------------------------*/ + +int device_consistency_message_create(device_consistency_message **message) +{ + int result = 0; + device_consistency_message *result_message = 0; + + result_message = malloc(sizeof(device_consistency_message)); + if(!result_message) { + result = SG_ERR_NOMEM; + goto complete; + } + memset(result_message, 0, sizeof(device_consistency_message)); + SIGNAL_INIT(result_message, device_consistency_message_destroy); + +complete: + if(result >= 0) { + *message = result_message; + } + return result; +} + +int device_consistency_message_create_from_pair(device_consistency_message **message, + device_consistency_commitment *commitment, + ec_key_pair *identity_key_pair, + signal_context *global_context) +{ + int result = 0; + device_consistency_message *result_message = 0; + signal_buffer *commitment_buffer = 0; + signal_buffer *signature_buffer = 0; + signal_buffer *vrf_output_buffer = 0; + signal_buffer *serialized_signature_buffer = 0; + Textsecure__DeviceConsistencyCodeMessage message_structure = TEXTSECURE__DEVICE_CONSISTENCY_CODE_MESSAGE__INIT; + size_t len = 0; + uint8_t *data = 0; + size_t result_size = 0; + + /* Create message instance */ + result = device_consistency_message_create(&result_message); + if(result < 0) { + goto complete; + } + + /* Calculate VRF signature */ + commitment_buffer = device_consistency_commitment_get_serialized(commitment); + result = curve_calculate_vrf_signature(global_context, &signature_buffer, + ec_key_pair_get_private(identity_key_pair), + signal_buffer_data(commitment_buffer), signal_buffer_len(commitment_buffer)); + if(result < 0) { + goto complete; + } + + /* Verify VRF signature */ + result = curve_verify_vrf_signature(global_context, &vrf_output_buffer, + ec_key_pair_get_public(identity_key_pair), + signal_buffer_data(commitment_buffer), signal_buffer_len(commitment_buffer), + signal_buffer_data(signature_buffer), signal_buffer_len(signature_buffer)); + if(result < 0) { + goto complete; + } + + result_message->generation = device_consistency_commitment_get_generation(commitment); + + /* Create and assign the signature */ + result = device_consistency_signature_create(&result_message->signature, + signal_buffer_data(signature_buffer), signal_buffer_len(signature_buffer), + signal_buffer_data(vrf_output_buffer), signal_buffer_len(vrf_output_buffer)); + if(result < 0) { + goto complete; + } + + serialized_signature_buffer = device_consistency_signature_get_signature(result_message->signature); + + /* Serialize the message */ + message_structure.generation = device_consistency_commitment_get_generation(commitment); + message_structure.has_generation = 1; + message_structure.signature.data = signal_buffer_data(serialized_signature_buffer); + message_structure.signature.len = signal_buffer_len(serialized_signature_buffer); + message_structure.has_signature = 1; + + len = textsecure__device_consistency_code_message__get_packed_size(&message_structure); + result_message->serialized = signal_buffer_alloc(len); + if(!result_message->serialized) { + result = SG_ERR_NOMEM; + goto complete; + } + + data = signal_buffer_data(result_message->serialized); + + result_size = textsecure__device_consistency_code_message__pack(&message_structure, data); + if(result_size != len) { + result = SG_ERR_INVALID_PROTO_BUF; + goto complete; + } + +complete: + signal_buffer_free(signature_buffer); + signal_buffer_free(vrf_output_buffer); + if(result >= 0) { + *message = result_message; + } + else { + SIGNAL_UNREF(result_message); + } + if(result == SG_ERR_INVALID_KEY || result == SG_ERR_VRF_SIG_VERIF_FAILED) { + result = SG_ERR_UNKNOWN; + } + return result; +} + +int device_consistency_message_create_from_serialized(device_consistency_message **message, + device_consistency_commitment *commitment, + const uint8_t *serialized_data, size_t serialized_len, + ec_public_key *identity_key, + signal_context *global_context) +{ + int result = 0; + device_consistency_message *result_message = 0; + Textsecure__DeviceConsistencyCodeMessage *message_structure = 0; + signal_buffer *commitment_buffer = 0; + signal_buffer *vrf_output_buffer = 0; + + /* Create message instance */ + result = device_consistency_message_create(&result_message); + if(result < 0) { + goto complete; + } + + /* Deserialize the message */ + message_structure = textsecure__device_consistency_code_message__unpack(0, serialized_len, serialized_data); + if(!message_structure) { + result = SG_ERR_INVALID_PROTO_BUF; + goto complete; + } + + if(!message_structure->has_generation || !message_structure->has_signature) { + result = SG_ERR_INVALID_PROTO_BUF; + goto complete; + } + + /* Verify VRF signature */ + commitment_buffer = device_consistency_commitment_get_serialized(commitment); + result = curve_verify_vrf_signature(global_context, &vrf_output_buffer, + identity_key, + signal_buffer_data(commitment_buffer), signal_buffer_len(commitment_buffer), + message_structure->signature.data, message_structure->signature.len); + if(result < 0) { + goto complete; + } + + /* Assign the message fields */ + result_message->generation = message_structure->generation; + + device_consistency_signature_create(&result_message->signature, + message_structure->signature.data, message_structure->signature.len, + signal_buffer_data(vrf_output_buffer), signal_buffer_len(vrf_output_buffer)); + if(result < 0) { + goto complete; + } + + result_message->serialized = signal_buffer_create(serialized_data, serialized_len); + if(!result_message->serialized) { + result = SG_ERR_NOMEM; + } + +complete: + if(message_structure) { + textsecure__device_consistency_code_message__free_unpacked(message_structure, 0); + } + signal_buffer_free(vrf_output_buffer); + if(result >= 0) { + *message = result_message; + } + else { + SIGNAL_UNREF(result_message); + } + if(result == SG_ERR_INVALID_PROTO_BUF + || result == SG_ERR_INVALID_KEY + || result == SG_ERR_VRF_SIG_VERIF_FAILED) { + result = SG_ERR_INVALID_MESSAGE; + } + return result; +} + +signal_buffer *device_consistency_message_get_serialized(const device_consistency_message *message) +{ + assert(message); + return message->serialized; +} + +device_consistency_signature *device_consistency_message_get_signature(const device_consistency_message *message) +{ + assert(message); + return message->signature; +} + +uint32_t device_consistency_signature_get_generation(const device_consistency_message *message) +{ + assert(message); + return message->generation; +} + +void device_consistency_message_destroy(signal_type_base *type) +{ + device_consistency_message *message = (device_consistency_message *)type; + SIGNAL_UNREF(message->signature); + signal_buffer_free(message->serialized); + free(message); +} + +/*------------------------------------------------------------------------*/ + +int device_consistency_code_generate_for(device_consistency_commitment *commitment, + device_consistency_signature_list *signatures, + char **code_string, + signal_context *global_context) +{ + int result = 0; + char *result_string = 0; + void *digest_context = 0; + device_consistency_signature_list *sorted_list = 0; + uint8_t version_data[2]; + signal_buffer *commitment_buffer; + unsigned int list_size; + unsigned int i; + signal_buffer *hash_buffer = 0; + uint8_t *data = 0; + size_t len = 0; + char *encoded_string = 0; + + sorted_list = device_consistency_signature_list_copy(signatures); + if(!sorted_list) { + result = SG_ERR_NOMEM; + goto complete; + } + + device_consistency_signature_list_sort(sorted_list); + + result = signal_sha512_digest_init(global_context, &digest_context); + if(result < 0) { + goto complete; + } + + version_data[1] = (uint8_t)(CODE_VERSION); + version_data[0] = (uint8_t)(CODE_VERSION >> 8); + + result = signal_sha512_digest_update(global_context, digest_context, + version_data, sizeof(version_data)); + if(result < 0) { + goto complete; + } + + commitment_buffer = device_consistency_commitment_get_serialized(commitment); + result = signal_sha512_digest_update(global_context, digest_context, + signal_buffer_data(commitment_buffer), + signal_buffer_len(commitment_buffer)); + if(result < 0) { + goto complete; + } + + list_size = device_consistency_signature_list_size(sorted_list); + for(i = 0; i < list_size; i++) { + device_consistency_signature *signature = device_consistency_signature_list_at(sorted_list, i); + signal_buffer *vrf_output = device_consistency_signature_get_vrf_output(signature); + + result = signal_sha512_digest_update(global_context, digest_context, + signal_buffer_data(vrf_output), + signal_buffer_len(vrf_output)); + if(result < 0) { + goto complete; + } + } + + result = signal_sha512_digest_final(global_context, digest_context, &hash_buffer); + if(result < 0) { + goto complete; + } + + data = signal_buffer_data(hash_buffer); + len = signal_buffer_len(hash_buffer); + + if(len < 10) { + result = SG_ERR_UNKNOWN; + goto complete; + } + + encoded_string = malloc(11); + if(!encoded_string) { + result = SG_ERR_NOMEM; + goto complete; + } + + for(i = 0; i < 10; i += 5) { + uint64_t chunk = ((uint64_t)data[i] & 0xFFL) << 32 | + ((uint64_t)data[i + 1] & 0xFFL) << 24 | + ((uint64_t)data[i + 2] & 0xFFL) << 16 | + ((uint64_t)data[i + 3] & 0xFFL) << 8 | + ((uint64_t)data[i + 4] & 0xFFL); +#if _WINDOWS + sprintf_s(encoded_string + i, 6, "%05d", (int)(chunk % 100000)); +#else + snprintf(encoded_string + i, 6, "%05d", (int)(chunk % 100000)); +#endif + } + + result_string = malloc(7); + if(!result_string) { + result = SG_ERR_NOMEM; + goto complete; + } + + memcpy(result_string, encoded_string, 6); + result_string[6] = '\0'; + +complete: + if(sorted_list) { + device_consistency_signature_list_free(sorted_list); + } + if(digest_context) { + signal_sha512_digest_cleanup(global_context, digest_context); + } + signal_buffer_free(hash_buffer); + free(encoded_string); + if(result >= 0) { + *code_string = result_string; + } + return result; +} + +/*------------------------------------------------------------------------*/ + +device_consistency_signature_list *device_consistency_signature_list_alloc() +{ + device_consistency_signature_list *list = malloc(sizeof(device_consistency_signature_list)); + if(!list) { + return 0; + } + memset(list, 0, sizeof(device_consistency_signature_list)); + utarray_new(list->values, &ut_ptr_icd); + return list; +} + +device_consistency_signature_list *device_consistency_signature_list_copy(const device_consistency_signature_list *list) +{ + device_consistency_signature_list *result = 0; + unsigned int size; + unsigned int i; + device_consistency_signature **p; + + result = device_consistency_signature_list_alloc(); + if(!result) { + return 0; + } + + size = utarray_len(list->values); + + utarray_reserve(result->values, size); + + for (i = 0; i < size; i++) { + p = (device_consistency_signature **)utarray_eltptr(list->values, i); + device_consistency_signature_list_push_back(result, *p); + } + + return result; +} + +void device_consistency_signature_list_push_back(device_consistency_signature_list *list, device_consistency_signature *value) +{ + assert(list); + assert(value); + SIGNAL_REF(value); + utarray_push_back(list->values, &value); +} + +unsigned int device_consistency_signature_list_size(const device_consistency_signature_list *list) +{ + assert(list); + return utarray_len(list->values); +} + +device_consistency_signature *device_consistency_signature_list_at(const device_consistency_signature_list *list, unsigned int index) +{ + device_consistency_signature **value = 0; + + assert(list); + assert(index < utarray_len(list->values)); + + value = (device_consistency_signature **)utarray_eltptr(list->values, index); + + assert(*value); + + return *value; +} + +int device_consistency_signature_list_sort_comparator(const void *a, const void *b) +{ + int result; + const device_consistency_signature *sig1 = *((const device_consistency_signature **)a); + const device_consistency_signature *sig2 = *((const device_consistency_signature **)b); + signal_buffer *buf1 = device_consistency_signature_get_signature(sig1); + signal_buffer *buf2 = device_consistency_signature_get_signature(sig2); + size_t len1 = signal_buffer_len(buf1); + size_t len2 = signal_buffer_len(buf2); + + if(len1 == len2) { + result = memcmp(signal_buffer_data(buf1), signal_buffer_data(buf2), len1); + } + else { + result = len1 - len2; + } + + return result; +} + +void device_consistency_signature_list_sort(device_consistency_signature_list *list) +{ + assert(list); + utarray_sort(list->values, device_consistency_signature_list_sort_comparator); +} + +void device_consistency_signature_list_free(device_consistency_signature_list *list) +{ + unsigned int size; + unsigned int i; + device_consistency_signature **p; + if(list) { + size = utarray_len(list->values); + for (i = 0; i < size; i++) { + p = (device_consistency_signature **)utarray_eltptr(list->values, i); + SIGNAL_UNREF(*p); + } + utarray_free(list->values); + free(list); + } +} diff --git a/libs/libaxolotl/src/device_consistency.h b/libs/libaxolotl/src/device_consistency.h new file mode 100644 index 0000000000..37c683052f --- /dev/null +++ b/libs/libaxolotl/src/device_consistency.h @@ -0,0 +1,60 @@ +#ifndef DEVICE_CONSISTENCY_H +#define DEVICE_CONSISTENCY_H + +#include "signal_protocol_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int device_consistency_signature_create(device_consistency_signature **signature, + const uint8_t *signature_data, size_t signature_len, + const uint8_t *vrf_output_data, size_t vrf_output_len); + +signal_buffer *device_consistency_signature_get_signature(const device_consistency_signature *signature); +signal_buffer *device_consistency_signature_get_vrf_output(const device_consistency_signature *signature); + +void device_consistency_signature_destroy(signal_type_base *type); + +int device_consistency_commitment_create(device_consistency_commitment **commitment, + uint32_t generation, ec_public_key_list *identity_key_list, + signal_context *global_context); + +uint32_t device_consistency_commitment_get_generation(const device_consistency_commitment *commitment); +signal_buffer *device_consistency_commitment_get_serialized(const device_consistency_commitment *commitment); + +void device_consistency_commitment_destroy(signal_type_base *type); + +int device_consistency_message_create_from_pair(device_consistency_message **message, + device_consistency_commitment *commitment, + ec_key_pair *identity_key_pair, + signal_context *global_context); +int device_consistency_message_create_from_serialized(device_consistency_message **message, + device_consistency_commitment *commitment, + const uint8_t *serialized_data, size_t serialized_len, + ec_public_key *identity_key, + signal_context *global_context); + +signal_buffer *device_consistency_message_get_serialized(const device_consistency_message *message); +device_consistency_signature *device_consistency_message_get_signature(const device_consistency_message *message); +uint32_t device_consistency_signature_get_generation(const device_consistency_message *message); + +void device_consistency_message_destroy(signal_type_base *type); + +int device_consistency_code_generate_for(device_consistency_commitment *commitment, + device_consistency_signature_list *signatures, + char **code_string, + signal_context *global_context); + +device_consistency_signature_list *device_consistency_signature_list_alloc(void); +device_consistency_signature_list *device_consistency_signature_list_copy(const device_consistency_signature_list *list); +void device_consistency_signature_list_push_back(device_consistency_signature_list *list, device_consistency_signature *value); +unsigned int device_consistency_signature_list_size(const device_consistency_signature_list *list); +device_consistency_signature *device_consistency_signature_list_at(const device_consistency_signature_list *list, unsigned int index); +void device_consistency_signature_list_free(device_consistency_signature_list *list); + +#ifdef __cplusplus +} +#endif + +#endif /* DEVICE_CONSISTENCY_H */ diff --git a/libs/libaxolotl/src/fingerprint.c b/libs/libaxolotl/src/fingerprint.c index f5a00248b2..42827825cc 100644 --- a/libs/libaxolotl/src/fingerprint.c +++ b/libs/libaxolotl/src/fingerprint.c @@ -3,21 +3,24 @@ #include <assert.h> #include <string.h> -#include "axolotl_internal.h" #include "FingerprintProtocol.pb-c.h" +#include "signal_protocol_internal.h" #define VERSION 0 +#define SHA512_DIGEST_LENGTH 64 + +#define MAX(a,b) (((a)>(b))?(a):(b)) struct fingerprint { - axolotl_type_base base; + signal_type_base base; displayable_fingerprint *displayable; scannable_fingerprint *scannable; }; struct displayable_fingerprint { - axolotl_type_base base; + signal_type_base base; char *local_fingerprint; char *remote_fingerprint; char *display_text; @@ -25,7 +28,7 @@ struct displayable_fingerprint struct scannable_fingerprint { - axolotl_type_base base; + signal_type_base base; uint32_t version; char *local_stable_identifier; ec_public_key *local_identity_key; @@ -36,13 +39,13 @@ struct scannable_fingerprint struct fingerprint_generator { int iterations; - axolotl_context *global_context; + signal_context *global_context; }; static int fingerprint_generator_create_display_string(fingerprint_generator *generator, char **display_string, const char *local_stable_identifier, ec_public_key *identity_key); -int fingerprint_generator_create(fingerprint_generator **generator, int iterations, axolotl_context *global_context) +int fingerprint_generator_create(fingerprint_generator **generator, int iterations, signal_context *global_context) { fingerprint_generator *result_generator; @@ -50,7 +53,7 @@ int fingerprint_generator_create(fingerprint_generator **generator, int iteratio result_generator = malloc(sizeof(fingerprint_generator)); if(!result_generator) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result_generator, 0, sizeof(fingerprint_generator)); @@ -106,8 +109,8 @@ complete: if(displayable_remote) { free(displayable_remote); } - AXOLOTL_UNREF(displayable); - AXOLOTL_UNREF(scannable); + SIGNAL_UNREF(displayable); + SIGNAL_UNREF(scannable); if(result >= 0) { *fingerprint_val = result_fingerprint; } @@ -119,9 +122,10 @@ int fingerprint_generator_create_display_string(fingerprint_generator *generator { int result = 0; char *result_string = 0; - axolotl_buffer *identity_buffer = 0; - axolotl_buffer *hash_buffer = 0; - axolotl_buffer *hash_out_buffer = 0; + void *digest_context = 0; + signal_buffer *identity_buffer = 0; + signal_buffer *hash_buffer = 0; + signal_buffer *hash_out_buffer = 0; uint8_t *data = 0; size_t len = 0; int i = 0; @@ -129,55 +133,74 @@ int fingerprint_generator_create_display_string(fingerprint_generator *generator assert(generator); assert(stable_identifier); assert(identity_key); - assert(generator->global_context->crypto_provider.sha512_digest_func); + + result = signal_sha512_digest_init(generator->global_context, &digest_context); + if(result < 0) { + goto complete; + } result = ec_public_key_serialize(&identity_buffer, identity_key); if(result < 0) { goto complete; } - len = 2 + axolotl_buffer_len(identity_buffer) + strlen(stable_identifier); + len = 2 + signal_buffer_len(identity_buffer) + strlen(stable_identifier); - hash_buffer = axolotl_buffer_alloc(len); + hash_buffer = signal_buffer_alloc(len); if(!hash_buffer) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(hash_buffer); + data = signal_buffer_data(hash_buffer); memset(data, 0, len); data[0] = 0; data[1] = (uint8_t)VERSION; - memcpy(data + 2, axolotl_buffer_data(identity_buffer), axolotl_buffer_len(identity_buffer)); - memcpy(data + 2 + axolotl_buffer_len(identity_buffer), stable_identifier, strlen(stable_identifier)); + memcpy(data + 2, signal_buffer_data(identity_buffer), signal_buffer_len(identity_buffer)); + memcpy(data + 2 + signal_buffer_len(identity_buffer), stable_identifier, strlen(stable_identifier)); for(i = 0; i < generator->iterations; i++) { - result = axolotl_sha512_digest(generator->global_context, - &hash_out_buffer, - axolotl_buffer_data(hash_buffer), - axolotl_buffer_len(hash_buffer)); + data = signal_buffer_data(hash_buffer); + len = signal_buffer_len(hash_buffer); + + result = signal_sha512_digest_update(generator->global_context, + digest_context, data, len); if(result < 0) { goto complete; } - axolotl_buffer_free(hash_buffer); + result = signal_sha512_digest_update(generator->global_context, + digest_context, + signal_buffer_data(identity_buffer), + signal_buffer_len(identity_buffer)); + if(result < 0) { + goto complete; + } + + result = signal_sha512_digest_final(generator->global_context, + digest_context, &hash_out_buffer); + if(result < 0) { + goto complete; + } + + signal_buffer_free(hash_buffer); hash_buffer = hash_out_buffer; hash_out_buffer = 0; } - data = axolotl_buffer_data(hash_buffer); - len = axolotl_buffer_len(hash_buffer); + data = signal_buffer_data(hash_buffer); + len = signal_buffer_len(hash_buffer); if(len < 30) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } result_string = malloc(31); if(!result_string) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -195,9 +218,12 @@ int fingerprint_generator_create_display_string(fingerprint_generator *generator } complete: - axolotl_buffer_free(identity_buffer); - axolotl_buffer_free(hash_buffer); - axolotl_buffer_free(hash_out_buffer); + if(digest_context) { + signal_sha512_digest_cleanup(generator->global_context, digest_context); + } + signal_buffer_free(identity_buffer); + signal_buffer_free(hash_buffer); + signal_buffer_free(hash_out_buffer); if(result >= 0) { *display_string = result_string; } @@ -215,18 +241,18 @@ int fingerprint_create(fingerprint **fingerprint_val, displayable_fingerprint *d { fingerprint *result = malloc(sizeof(fingerprint)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result, 0, sizeof(fingerprint)); - AXOLOTL_INIT(result, fingerprint_destroy); + SIGNAL_INIT(result, fingerprint_destroy); if(displayable) { result->displayable = displayable; - AXOLOTL_REF(displayable); + SIGNAL_REF(displayable); } if(scannable) { result->scannable = scannable; - AXOLOTL_REF(scannable); + SIGNAL_REF(scannable); } *fingerprint_val = result; @@ -246,11 +272,11 @@ scannable_fingerprint *fingerprint_get_scannable(fingerprint *fingerprint_val) return fingerprint_val->scannable; } -void fingerprint_destroy(axolotl_type_base *type) +void fingerprint_destroy(signal_type_base *type) { fingerprint *fingerprint_val = (fingerprint *)type; - AXOLOTL_UNREF(fingerprint_val->displayable); - AXOLOTL_UNREF(fingerprint_val->scannable); + SIGNAL_UNREF(fingerprint_val->displayable); + SIGNAL_UNREF(fingerprint_val->scannable); free(fingerprint_val); } @@ -263,26 +289,26 @@ int displayable_fingerprint_create(displayable_fingerprint **displayable, const char *display_text = 0; if(!local_fingerprint || !remote_fingerprint) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } result_displayable = malloc(sizeof(displayable_fingerprint)); if(!result_displayable) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result_displayable, 0, sizeof(displayable_fingerprint)); - AXOLOTL_INIT(result_displayable, displayable_fingerprint_destroy); + SIGNAL_INIT(result_displayable, displayable_fingerprint_destroy); result_displayable->local_fingerprint = strdup(local_fingerprint); if(!result_displayable->local_fingerprint) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } result_displayable->remote_fingerprint = strdup(remote_fingerprint); if(!result_displayable->remote_fingerprint) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -291,7 +317,7 @@ int displayable_fingerprint_create(displayable_fingerprint **displayable, const display_text = malloc(local_len + remote_len + 1); if(!display_text) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -308,7 +334,7 @@ int displayable_fingerprint_create(displayable_fingerprint **displayable, const complete: if(result < 0) { - AXOLOTL_UNREF(result_displayable); + SIGNAL_UNREF(result_displayable); } else { *displayable = result_displayable; @@ -335,7 +361,7 @@ const char *displayable_fingerprint_text(displayable_fingerprint *displayable) return displayable->display_text; } -void displayable_fingerprint_destroy(axolotl_type_base *type) +void displayable_fingerprint_destroy(signal_type_base *type) { displayable_fingerprint *displayable = (displayable_fingerprint *)type; if(displayable->local_fingerprint) { @@ -360,40 +386,40 @@ int scannable_fingerprint_create(scannable_fingerprint **scannable, if(!local_stable_identifier || !local_identity_key || !remote_stable_identifier || !remote_identity_key) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } result_scannable = malloc(sizeof(scannable_fingerprint)); if(!result_scannable) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result_scannable, 0, sizeof(scannable_fingerprint)); - AXOLOTL_INIT(result_scannable, scannable_fingerprint_destroy); + SIGNAL_INIT(result_scannable, scannable_fingerprint_destroy); result_scannable->version = version; result_scannable->local_stable_identifier = strdup(local_stable_identifier); if(!result_scannable->local_stable_identifier) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } result_scannable->local_identity_key = local_identity_key; - AXOLOTL_REF(local_identity_key); + SIGNAL_REF(local_identity_key); result_scannable->remote_stable_identifier = strdup(remote_stable_identifier); if(!result_scannable->remote_stable_identifier) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } result_scannable->remote_identity_key = remote_identity_key; - AXOLOTL_REF(remote_identity_key); + SIGNAL_REF(remote_identity_key); complete: if(result < 0) { - AXOLOTL_UNREF(result_scannable); + SIGNAL_UNREF(result_scannable); } else { *scannable = result_scannable; @@ -402,11 +428,11 @@ complete: return result; } -int scannable_fingerprint_serialize(axolotl_buffer **buffer, const scannable_fingerprint *scannable) +int scannable_fingerprint_serialize(signal_buffer **buffer, const scannable_fingerprint *scannable) { int result = 0; size_t result_size = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; Textsecure__CombinedFingerprint combined_fingerprint = TEXTSECURE__COMBINED_FINGERPRINT__INIT; Textsecure__FingerprintData local_fingerprint = TEXTSECURE__FINGERPRINT_DATA__INIT; Textsecure__FingerprintData remote_fingerprint = TEXTSECURE__FINGERPRINT_DATA__INIT; @@ -417,7 +443,7 @@ int scannable_fingerprint_serialize(axolotl_buffer **buffer, const scannable_fin combined_fingerprint.has_version = 1; if(scannable->local_stable_identifier && scannable->local_identity_key) { - axolotl_str_serialize_protobuf(&local_fingerprint.identifier, scannable->local_stable_identifier); + signal_protocol_str_serialize_protobuf(&local_fingerprint.identifier, scannable->local_stable_identifier); local_fingerprint.has_identifier = 1; result = ec_public_key_serialize_protobuf(&local_fingerprint.publickey, scannable->local_identity_key); @@ -430,7 +456,7 @@ int scannable_fingerprint_serialize(axolotl_buffer **buffer, const scannable_fin } if(scannable->remote_stable_identifier && scannable->remote_identity_key) { - axolotl_str_serialize_protobuf(&remote_fingerprint.identifier, scannable->remote_stable_identifier); + signal_protocol_str_serialize_protobuf(&remote_fingerprint.identifier, scannable->remote_stable_identifier); remote_fingerprint.has_identifier = 1; result = ec_public_key_serialize_protobuf(&remote_fingerprint.publickey, scannable->remote_identity_key); @@ -444,17 +470,17 @@ int scannable_fingerprint_serialize(axolotl_buffer **buffer, const scannable_fin len = textsecure__combined_fingerprint__get_packed_size(&combined_fingerprint); - result_buf = axolotl_buffer_alloc(len); + result_buf = signal_buffer_alloc(len); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); result_size = textsecure__combined_fingerprint__pack(&combined_fingerprint, data); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } @@ -472,7 +498,7 @@ complete: return result; } -int scannable_fingerprint_deserialize(scannable_fingerprint **scannable, const uint8_t *data, size_t len, axolotl_context *global_context) +int scannable_fingerprint_deserialize(scannable_fingerprint **scannable, const uint8_t *data, size_t len, signal_context *global_context) { int result = 0; Textsecure__CombinedFingerprint *combined_fingerprint = 0; @@ -484,7 +510,7 @@ int scannable_fingerprint_deserialize(scannable_fingerprint **scannable, const u combined_fingerprint = textsecure__combined_fingerprint__unpack(0, len, data); if(!combined_fingerprint) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } @@ -494,9 +520,9 @@ int scannable_fingerprint_deserialize(scannable_fingerprint **scannable, const u if(combined_fingerprint->localfingerprint) { if(combined_fingerprint->localfingerprint->has_identifier) { - local_stable_identifier = axolotl_str_deserialize_protobuf(&combined_fingerprint->localfingerprint->identifier); + local_stable_identifier = signal_protocol_str_deserialize_protobuf(&combined_fingerprint->localfingerprint->identifier); if(!local_stable_identifier) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } } @@ -513,9 +539,9 @@ int scannable_fingerprint_deserialize(scannable_fingerprint **scannable, const u if(combined_fingerprint->remotefingerprint) { if(combined_fingerprint->remotefingerprint->has_identifier) { - remote_stable_identifier = axolotl_str_deserialize_protobuf(&combined_fingerprint->remotefingerprint->identifier); + remote_stable_identifier = signal_protocol_str_deserialize_protobuf(&combined_fingerprint->remotefingerprint->identifier); if(!remote_stable_identifier) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } } @@ -542,13 +568,13 @@ complete: free(local_stable_identifier); } if(local_identity_key) { - AXOLOTL_UNREF(local_identity_key); + SIGNAL_UNREF(local_identity_key); } if(remote_stable_identifier) { free(remote_stable_identifier); } if(remote_identity_key) { - AXOLOTL_UNREF(remote_identity_key); + SIGNAL_UNREF(remote_identity_key); } return result; } @@ -587,15 +613,15 @@ int scannable_fingerprint_compare(scannable_fingerprint *scannable, const scanna { if(!other_scannable->remote_identity_key || !other_scannable->local_identity_key || other_scannable->version != scannable->version) { - return AX_ERR_FP_VERSION_MISMATCH; + return SG_ERR_FP_VERSION_MISMATCH; } if(strcmp(scannable->local_stable_identifier, other_scannable->remote_stable_identifier) != 0) { - return AX_ERR_FP_IDENT_MISMATCH; + return SG_ERR_FP_IDENT_MISMATCH; } if(strcmp(scannable->remote_stable_identifier, other_scannable->local_stable_identifier) != 0) { - return AX_ERR_FP_IDENT_MISMATCH; + return SG_ERR_FP_IDENT_MISMATCH; } if(ec_public_key_compare(scannable->local_identity_key, other_scannable->remote_identity_key) != 0) { @@ -609,7 +635,7 @@ int scannable_fingerprint_compare(scannable_fingerprint *scannable, const scanna return 1; } -void scannable_fingerprint_destroy(axolotl_type_base *type) +void scannable_fingerprint_destroy(signal_type_base *type) { scannable_fingerprint *scannable = (scannable_fingerprint *)type; @@ -617,13 +643,13 @@ void scannable_fingerprint_destroy(axolotl_type_base *type) free(scannable->local_stable_identifier); } - AXOLOTL_UNREF(scannable->local_identity_key); + SIGNAL_UNREF(scannable->local_identity_key); if(scannable->remote_stable_identifier) { free(scannable->remote_stable_identifier); } - AXOLOTL_UNREF(scannable->remote_identity_key); + SIGNAL_UNREF(scannable->remote_identity_key); free(scannable); } diff --git a/libs/libaxolotl/src/fingerprint.h b/libs/libaxolotl/src/fingerprint.h index 25d80a4e77..4d61e4f788 100644 --- a/libs/libaxolotl/src/fingerprint.h +++ b/libs/libaxolotl/src/fingerprint.h @@ -1,7 +1,7 @@ #ifndef FINGERPRINT_H #define FINGERPRINT_H -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { @@ -23,7 +23,7 @@ extern "C" { * @param global_context the global library context * @return 0 on success, or negative on failure */ -int fingerprint_generator_create(fingerprint_generator **generator, int iterations, axolotl_context *global_context); +int fingerprint_generator_create(fingerprint_generator **generator, int iterations, signal_context *global_context); /** * Generate a scannable and displayble fingerprint. @@ -45,21 +45,21 @@ void fingerprint_generator_free(fingerprint_generator *generator); int fingerprint_create(fingerprint **fingerprint_val, displayable_fingerprint *displayable, scannable_fingerprint *scannable); displayable_fingerprint *fingerprint_get_displayable(fingerprint *fingerprint_val); scannable_fingerprint *fingerprint_get_scannable(fingerprint *fingerprint_val); -void fingerprint_destroy(axolotl_type_base *type); +void fingerprint_destroy(signal_type_base *type); int displayable_fingerprint_create(displayable_fingerprint **displayable, const char *local_fingerprint, const char *remote_fingerprint); const char *displayable_fingerprint_local(displayable_fingerprint *displayable); const char *displayable_fingerprint_remote(displayable_fingerprint *displayable); const char *displayable_fingerprint_text(displayable_fingerprint *displayable); -void displayable_fingerprint_destroy(axolotl_type_base *type); +void displayable_fingerprint_destroy(signal_type_base *type); int scannable_fingerprint_create(scannable_fingerprint **scannable, uint32_t version, const char *local_stable_identifier, ec_public_key *local_identity_key, const char *remote_stable_identifier, ec_public_key *remote_identity_key); -int scannable_fingerprint_serialize(axolotl_buffer **buffer, const scannable_fingerprint *scannable); -int scannable_fingerprint_deserialize(scannable_fingerprint **scannable, const uint8_t *data, size_t len, axolotl_context *global_context); +int scannable_fingerprint_serialize(signal_buffer **buffer, const scannable_fingerprint *scannable); +int scannable_fingerprint_deserialize(scannable_fingerprint **scannable, const uint8_t *data, size_t len, signal_context *global_context); uint32_t scannable_fingerprint_get_version(scannable_fingerprint *scannable); const char *scannable_fingerprint_get_local_stable_identifier(scannable_fingerprint *scannable); ec_public_key *scannable_fingerprint_get_local_identity_key(scannable_fingerprint *scannable); @@ -72,12 +72,12 @@ ec_public_key *scannable_fingerprint_get_remote_identity_key(scannable_fingerpri * @param other_scannable The data from the scanned code * @retval 1 if the scannable codes match * @retval 0 if the scannable codes do not match - * @retval AX_ERR_FP_VERSION_MISMATCH if the scanned fingerprint is the wrong version - * @retval AX_ERR_FP_IDENT_MISMATCH if the scanned fingerprint is for the wrong stable identifier + * @retval SG_ERR_FP_VERSION_MISMATCH if the scanned fingerprint is the wrong version + * @retval SG_ERR_FP_IDENT_MISMATCH if the scanned fingerprint is for the wrong stable identifier */ int scannable_fingerprint_compare(scannable_fingerprint *scannable, const scannable_fingerprint *other_scannable); -void scannable_fingerprint_destroy(axolotl_type_base *type); +void scannable_fingerprint_destroy(signal_type_base *type); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/group_cipher.c b/libs/libaxolotl/src/group_cipher.c index 752c2e16d4..1b6f8af2c9 100644 --- a/libs/libaxolotl/src/group_cipher.c +++ b/libs/libaxolotl/src/group_cipher.c @@ -2,28 +2,28 @@ #include <assert.h> #include <string.h> -#include "axolotl_internal.h" #include "protocol.h" #include "sender_key.h" #include "sender_key_record.h" #include "sender_key_state.h" +#include "signal_protocol_internal.h" struct group_cipher { - axolotl_store_context *store; - const axolotl_sender_key_name *sender_key_id; - axolotl_context *global_context; - int (*decrypt_callback)(group_cipher *cipher, axolotl_buffer *plaintext, void *decrypt_context); + signal_protocol_store_context *store; + const signal_protocol_sender_key_name *sender_key_id; + signal_context *global_context; + int (*decrypt_callback)(group_cipher *cipher, signal_buffer *plaintext, void *decrypt_context); int inside_callback; void *user_data; }; static int group_cipher_get_sender_key(group_cipher *cipher, sender_message_key **sender_key, sender_key_state *state, uint32_t iteration); -static int group_cipher_decrypt_callback(group_cipher *cipher, axolotl_buffer *plaintext, void *decrypt_context); +static int group_cipher_decrypt_callback(group_cipher *cipher, signal_buffer *plaintext, void *decrypt_context); int group_cipher_create(group_cipher **cipher, - axolotl_store_context *store, const axolotl_sender_key_name *sender_key_id, - axolotl_context *global_context) + signal_protocol_store_context *store, const signal_protocol_sender_key_name *sender_key_id, + signal_context *global_context) { group_cipher *result_cipher; @@ -32,7 +32,7 @@ int group_cipher_create(group_cipher **cipher, result_cipher = malloc(sizeof(group_cipher)); if(!result_cipher) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result_cipher, 0, sizeof(group_cipher)); @@ -57,7 +57,7 @@ void *group_cipher_get_user_data(group_cipher *cipher) } void group_cipher_set_decryption_callback(group_cipher *cipher, - int (*callback)(group_cipher *cipher, axolotl_buffer *plaintext, void *decrypt_context)) + int (*callback)(group_cipher *cipher, signal_buffer *plaintext, void *decrypt_context)) { assert(cipher); cipher->decrypt_callback = callback; @@ -71,21 +71,22 @@ int group_cipher_encrypt(group_cipher *cipher, sender_key_message *result_message = 0; sender_key_record *record = 0; sender_key_state *state = 0; + ec_private_key *signing_key_private = 0; sender_message_key *sender_key = 0; sender_chain_key *next_chain_key = 0; - axolotl_buffer *sender_cipher_key = 0; - axolotl_buffer *sender_cipher_iv = 0; - axolotl_buffer *ciphertext = 0; + signal_buffer *sender_cipher_key = 0; + signal_buffer *sender_cipher_iv = 0; + signal_buffer *ciphertext = 0; assert(cipher); - axolotl_lock(cipher->global_context); + signal_lock(cipher->global_context); if(cipher->inside_callback == 1) { - result = AX_ERR_INVAL; + result = SG_ERR_INVAL; goto complete; } - result = axolotl_sender_key_load_key(cipher->store, &record, cipher->sender_key_id); + result = signal_protocol_sender_key_load_key(cipher->store, &record, cipher->sender_key_id); if(result < 0) { goto complete; } @@ -95,6 +96,12 @@ int group_cipher_encrypt(group_cipher *cipher, goto complete; } + signing_key_private = sender_key_state_get_signing_key_private(state); + if(!signing_key_private) { + result = SG_ERR_NO_SESSION; + goto complete; + } + result = sender_chain_key_create_message_key(sender_key_state_get_chain_key(state), &sender_key); if(result < 0) { goto complete; @@ -103,9 +110,9 @@ int group_cipher_encrypt(group_cipher *cipher, sender_cipher_key = sender_message_key_get_cipher_key(sender_key); sender_cipher_iv = sender_message_key_get_iv(sender_key); - result = axolotl_encrypt(cipher->global_context, &ciphertext, AX_CIPHER_AES_CBC_PKCS5, - axolotl_buffer_data(sender_cipher_key), axolotl_buffer_len(sender_cipher_key), - axolotl_buffer_data(sender_cipher_iv), axolotl_buffer_len(sender_cipher_iv), + result = signal_encrypt(cipher->global_context, &ciphertext, SG_CIPHER_AES_CBC_PKCS5, + signal_buffer_data(sender_cipher_key), signal_buffer_len(sender_cipher_key), + signal_buffer_data(sender_cipher_iv), signal_buffer_len(sender_cipher_iv), padded_plaintext, padded_plaintext_len); if(result < 0) { goto complete; @@ -114,8 +121,8 @@ int group_cipher_encrypt(group_cipher *cipher, result = sender_key_message_create(&result_message, sender_key_state_get_key_id(state), sender_message_key_get_iteration(sender_key), - axolotl_buffer_data(ciphertext), axolotl_buffer_len(ciphertext), - sender_key_state_get_signing_key_private(state), + signal_buffer_data(ciphertext), signal_buffer_len(ciphertext), + signing_key_private, cipher->global_context); if(result < 0) { goto complete; @@ -128,55 +135,55 @@ int group_cipher_encrypt(group_cipher *cipher, sender_key_state_set_chain_key(state, next_chain_key); - result = axolotl_sender_key_store_key(cipher->store, cipher->sender_key_id, record); + result = signal_protocol_sender_key_store_key(cipher->store, cipher->sender_key_id, record); complete: if(result >= 0) { *encrypted_message = (ciphertext_message *)result_message; } else { - if(result == AX_ERR_INVALID_KEY_ID) { - result = AX_ERR_NO_SESSION; + if(result == SG_ERR_INVALID_KEY_ID) { + result = SG_ERR_NO_SESSION; } - AXOLOTL_UNREF(result_message); + SIGNAL_UNREF(result_message); } - axolotl_buffer_free(ciphertext); - AXOLOTL_UNREF(next_chain_key); - AXOLOTL_UNREF(sender_key); - AXOLOTL_UNREF(record); - axolotl_unlock(cipher->global_context); + signal_buffer_free(ciphertext); + SIGNAL_UNREF(next_chain_key); + SIGNAL_UNREF(sender_key); + SIGNAL_UNREF(record); + signal_unlock(cipher->global_context); return result; } int group_cipher_decrypt(group_cipher *cipher, sender_key_message *ciphertext, void *decrypt_context, - axolotl_buffer **plaintext) + signal_buffer **plaintext) { int result = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; sender_key_record *record = 0; sender_key_state *state = 0; sender_message_key *sender_key = 0; - axolotl_buffer *sender_cipher_key = 0; - axolotl_buffer *sender_cipher_iv = 0; - axolotl_buffer *ciphertext_body = 0; + signal_buffer *sender_cipher_key = 0; + signal_buffer *sender_cipher_iv = 0; + signal_buffer *ciphertext_body = 0; assert(cipher); - axolotl_lock(cipher->global_context); + signal_lock(cipher->global_context); if(cipher->inside_callback == 1) { - result = AX_ERR_INVAL; + result = SG_ERR_INVAL; goto complete; } - result = axolotl_sender_key_load_key(cipher->store, &record, cipher->sender_key_id); + result = signal_protocol_sender_key_load_key(cipher->store, &record, cipher->sender_key_id); if(result < 0) { goto complete; } if(sender_key_record_is_empty(record)) { - result = AX_ERR_NO_SESSION; - axolotl_log(cipher->global_context, AX_LOG_WARNING, "No sender key for: %s::%s::%d", + result = SG_ERR_NO_SESSION; + signal_log(cipher->global_context, SG_LOG_WARNING, "No sender key for: %s::%s::%d", cipher->sender_key_id->group_id, cipher->sender_key_id->sender.name, cipher->sender_key_id->sender.device_id); @@ -202,10 +209,10 @@ int group_cipher_decrypt(group_cipher *cipher, sender_cipher_iv = sender_message_key_get_iv(sender_key); ciphertext_body = sender_key_message_get_ciphertext(ciphertext); - result = axolotl_decrypt(cipher->global_context, &result_buf, AX_CIPHER_AES_CBC_PKCS5, - axolotl_buffer_data(sender_cipher_key), axolotl_buffer_len(sender_cipher_key), - axolotl_buffer_data(sender_cipher_iv), axolotl_buffer_len(sender_cipher_iv), - axolotl_buffer_data(ciphertext_body), axolotl_buffer_len(ciphertext_body)); + result = signal_decrypt(cipher->global_context, &result_buf, SG_CIPHER_AES_CBC_PKCS5, + signal_buffer_data(sender_cipher_key), signal_buffer_len(sender_cipher_key), + signal_buffer_data(sender_cipher_iv), signal_buffer_len(sender_cipher_iv), + signal_buffer_data(ciphertext_body), signal_buffer_len(ciphertext_body)); if(result < 0) { goto complete; } @@ -215,21 +222,21 @@ int group_cipher_decrypt(group_cipher *cipher, goto complete; } - result = axolotl_sender_key_store_key(cipher->store, cipher->sender_key_id, record); + result = signal_protocol_sender_key_store_key(cipher->store, cipher->sender_key_id, record); complete: - AXOLOTL_UNREF(sender_key); - AXOLOTL_UNREF(record); + SIGNAL_UNREF(sender_key); + SIGNAL_UNREF(record); if(result >= 0) { *plaintext = result_buf; } else { - if(result == AX_ERR_INVALID_KEY || result == AX_ERR_INVALID_KEY_ID) { - result = AX_ERR_INVALID_MESSAGE; + if(result == SG_ERR_INVALID_KEY || result == SG_ERR_INVALID_KEY_ID) { + result = SG_ERR_INVALID_MESSAGE; } - axolotl_buffer_free(result_buf); + signal_buffer_free(result_buf); } - axolotl_unlock(cipher->global_context); + signal_unlock(cipher->global_context); return result; } @@ -242,19 +249,19 @@ int group_cipher_get_sender_key(group_cipher *cipher, sender_message_key **sende sender_message_key *message_key = 0; chain_key = sender_key_state_get_chain_key(state); - AXOLOTL_REF(chain_key); + SIGNAL_REF(chain_key); if(sender_chain_key_get_iteration(chain_key) > iteration) { if(sender_key_state_has_sender_message_key(state, iteration)) { result_key = sender_key_state_remove_sender_message_key(state, iteration); if(!result_key) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; } goto complete; } else { - result = AX_ERR_DUPLICATE_MESSAGE; - axolotl_log(cipher->global_context, AX_LOG_WARNING, + result = SG_ERR_DUPLICATE_MESSAGE; + signal_log(cipher->global_context, SG_LOG_WARNING, "Received message with old counter: %d, %d", sender_chain_key_get_iteration(chain_key), iteration); goto complete; @@ -262,8 +269,8 @@ int group_cipher_get_sender_key(group_cipher *cipher, sender_message_key **sende } if(iteration - sender_chain_key_get_iteration(chain_key) > 2000) { - result = AX_ERR_INVALID_MESSAGE; - axolotl_log(cipher->global_context, AX_LOG_WARNING, "Over 2000 messages into the future!"); + result = SG_ERR_INVALID_MESSAGE; + signal_log(cipher->global_context, SG_LOG_WARNING, "Over 2000 messages into the future!"); goto complete; } @@ -277,14 +284,14 @@ int group_cipher_get_sender_key(group_cipher *cipher, sender_message_key **sende if(result < 0) { goto complete; } - AXOLOTL_UNREF(message_key); + SIGNAL_UNREF(message_key); result = sender_chain_key_create_next(chain_key, &next_chain_key); if(result < 0) { goto complete; } - AXOLOTL_UNREF(chain_key); + SIGNAL_UNREF(chain_key); chain_key = next_chain_key; next_chain_key = 0; } @@ -298,16 +305,16 @@ int group_cipher_get_sender_key(group_cipher *cipher, sender_message_key **sende result = sender_chain_key_create_message_key(chain_key, &result_key); complete: - AXOLOTL_UNREF(message_key); - AXOLOTL_UNREF(chain_key); - AXOLOTL_UNREF(next_chain_key); + SIGNAL_UNREF(message_key); + SIGNAL_UNREF(chain_key); + SIGNAL_UNREF(next_chain_key); if(result >= 0) { *sender_key = result_key; } return result; } -static int group_cipher_decrypt_callback(group_cipher *cipher, axolotl_buffer *plaintext, void *decrypt_context) +static int group_cipher_decrypt_callback(group_cipher *cipher, signal_buffer *plaintext, void *decrypt_context) { int result = 0; if(cipher->decrypt_callback) { diff --git a/libs/libaxolotl/src/group_cipher.h b/libs/libaxolotl/src/group_cipher.h index f78a574bbe..189910d9da 100644 --- a/libs/libaxolotl/src/group_cipher.h +++ b/libs/libaxolotl/src/group_cipher.h @@ -3,14 +3,14 @@ #include <stdint.h> #include <stddef.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { #endif /* - * The main entry point for Axolotl group encrypt/decrypt operations. + * The main entry point for Signal Protocol group encrypt/decrypt operations. * * Once a session has been established with group_session_builder and a * sender_key_distribution_message has been distributed to each member of @@ -27,14 +27,14 @@ extern "C" { * When finished, free the returned instance by calling group_cipher_free(). * * @param cipher set to a freshly allocated group cipher instance - * @param store the axolotl_store_context to store all state information in + * @param store the signal_protocol_store_context to store all state information in * @param sender_key_id the sender that messages will be encrypted to or decrypted from * @param global_context the global library context * @return 0 on success, or negative on failure */ int group_cipher_create(group_cipher **cipher, - axolotl_store_context *store, const axolotl_sender_key_name *sender_key_id, - axolotl_context *global_context); + signal_protocol_store_context *store, const signal_protocol_sender_key_name *sender_key_id, + signal_context *global_context); /** * Set the optional user data pointer for the group cipher. @@ -70,7 +70,7 @@ void *group_cipher_get_user_data(group_cipher *cipher); * @param user_data user data pointer provided to the callback */ void group_cipher_set_decryption_callback(group_cipher *cipher, - int (*callback)(group_cipher *cipher, axolotl_buffer *plaintext, void *decrypt_context)); + int (*callback)(group_cipher *cipher, signal_buffer *plaintext, void *decrypt_context)); /** * Encrypt a message. @@ -79,7 +79,7 @@ void group_cipher_set_decryption_callback(group_cipher *cipher, * @param padded_message_len The length of the data pointed to by padded_message * @param encrypted_message Set to a ciphertext message encrypted to the group+sender+device tuple. * - * @return AX_SUCCESS on success, negative on error + * @return SG_SUCCESS on success, negative on error */ int group_cipher_encrypt(group_cipher *cipher, const uint8_t *padded_plaintext, size_t padded_plaintext_len, @@ -93,16 +93,16 @@ int group_cipher_encrypt(group_cipher *cipher, * ciphertext, which is passed to the decryption callback function * @param plaintext Set to a newly allocated buffer containing the plaintext. * - * @retval AX_SUCCESS Success - * @retval AX_ERR_INVALID_MESSAGE if the input is not valid ciphertext. - * @retval AX_ERR_DUPLICATE_MESSAGE if the input is a message that has already been received. - * @retval AX_ERR_LEGACY_MESSAGE if the input is a message formatted by a protocol version that + * @retval SG_SUCCESS Success + * @retval SG_ERR_INVALID_MESSAGE if the input is not valid ciphertext. + * @retval SG_ERR_DUPLICATE_MESSAGE if the input is a message that has already been received. + * @retval SG_ERR_LEGACY_MESSAGE if the input is a message formatted by a protocol version that * is no longer supported. - * @retval AX_ERR_NO_SESSION if there is no established session for this contact. + * @retval SG_ERR_NO_SESSION if there is no established session for this contact. */ int group_cipher_decrypt(group_cipher *cipher, sender_key_message *ciphertext, void *decrypt_context, - axolotl_buffer **plaintext); + signal_buffer **plaintext); void group_cipher_free(group_cipher *cipher); diff --git a/libs/libaxolotl/src/group_session_builder.c b/libs/libaxolotl/src/group_session_builder.c index 4ac825b142..13db334c8e 100644 --- a/libs/libaxolotl/src/group_session_builder.c +++ b/libs/libaxolotl/src/group_session_builder.c @@ -2,21 +2,21 @@ #include <assert.h> #include <string.h> -#include "axolotl_internal.h" #include "sender_key_record.h" #include "sender_key_state.h" #include "sender_key.h" #include "protocol.h" #include "key_helper.h" +#include "signal_protocol_internal.h" struct group_session_builder { - axolotl_store_context *store; - axolotl_context *global_context; + signal_protocol_store_context *store; + signal_context *global_context; }; int group_session_builder_create(group_session_builder **builder, - axolotl_store_context *store, axolotl_context *global_context) + signal_protocol_store_context *store, signal_context *global_context) { group_session_builder *result = 0; @@ -25,7 +25,7 @@ int group_session_builder_create(group_session_builder **builder, result = malloc(sizeof(group_session_builder)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result, 0, sizeof(group_session_builder)); @@ -37,7 +37,7 @@ int group_session_builder_create(group_session_builder **builder, } int group_session_builder_process_session(group_session_builder *builder, - const axolotl_sender_key_name *sender_key_name, + const signal_protocol_sender_key_name *sender_key_name, sender_key_distribution_message *distribution_message) { int result = 0; @@ -45,9 +45,9 @@ int group_session_builder_process_session(group_session_builder *builder, assert(builder); assert(builder->store); - axolotl_lock(builder->global_context); + signal_lock(builder->global_context); - result = axolotl_sender_key_load_key(builder->store, &record, sender_key_name); + result = signal_protocol_sender_key_load_key(builder->store, &record, sender_key_name); if(result < 0) { goto complete; } @@ -61,48 +61,48 @@ int group_session_builder_process_session(group_session_builder *builder, goto complete; } - result = axolotl_sender_key_store_key(builder->store, sender_key_name, record); + result = signal_protocol_sender_key_store_key(builder->store, sender_key_name, record); complete: - AXOLOTL_UNREF(record); - axolotl_unlock(builder->global_context); + SIGNAL_UNREF(record); + signal_unlock(builder->global_context); return result; } int group_session_builder_create_session(group_session_builder *builder, sender_key_distribution_message **distribution_message, - const axolotl_sender_key_name *sender_key_name) + const signal_protocol_sender_key_name *sender_key_name) { int result = 0; sender_key_record *record = 0; sender_key_state *state = 0; uint32_t sender_key_id = 0; - axolotl_buffer *sender_key = 0; + signal_buffer *sender_key = 0; ec_key_pair *sender_signing_key = 0; sender_chain_key *chain_key = 0; - axolotl_buffer *seed = 0; + signal_buffer *seed = 0; assert(builder); assert(builder->store); - axolotl_lock(builder->global_context); + signal_lock(builder->global_context); - result = axolotl_sender_key_load_key(builder->store, &record, sender_key_name); + result = signal_protocol_sender_key_load_key(builder->store, &record, sender_key_name); if(result < 0) { goto complete; } if(sender_key_record_is_empty(record)) { - result = axolotl_key_helper_generate_sender_key_id(&sender_key_id, builder->global_context); + result = signal_protocol_key_helper_generate_sender_key_id(&sender_key_id, builder->global_context); if(result < 0) { goto complete; } - result = axolotl_key_helper_generate_sender_key(&sender_key, builder->global_context); + result = signal_protocol_key_helper_generate_sender_key(&sender_key, builder->global_context); if(result < 0) { goto complete; } - result = axolotl_key_helper_generate_sender_signing_key(&sender_signing_key, builder->global_context); + result = signal_protocol_key_helper_generate_sender_signing_key(&sender_signing_key, builder->global_context); if(result < 0) { goto complete; } @@ -112,7 +112,7 @@ int group_session_builder_create_session(group_session_builder *builder, goto complete; } - result = axolotl_sender_key_store_key(builder->store, sender_key_name, record); + result = signal_protocol_sender_key_store_key(builder->store, sender_key_name, record); if(result < 0) { goto complete; } @@ -129,15 +129,15 @@ int group_session_builder_create_session(group_session_builder *builder, result = sender_key_distribution_message_create(distribution_message, sender_key_state_get_key_id(state), sender_chain_key_get_iteration(chain_key), - axolotl_buffer_data(seed), axolotl_buffer_len(seed), + signal_buffer_data(seed), signal_buffer_len(seed), sender_key_state_get_signing_key_public(state), builder->global_context); complete: - axolotl_buffer_free(sender_key); - AXOLOTL_UNREF(sender_signing_key); - AXOLOTL_UNREF(record); - axolotl_unlock(builder->global_context); + signal_buffer_free(sender_key); + SIGNAL_UNREF(sender_signing_key); + SIGNAL_UNREF(record); + signal_unlock(builder->global_context); return result; } diff --git a/libs/libaxolotl/src/group_session_builder.h b/libs/libaxolotl/src/group_session_builder.h index b54807427e..1d87d53a7f 100644 --- a/libs/libaxolotl/src/group_session_builder.h +++ b/libs/libaxolotl/src/group_session_builder.h @@ -1,7 +1,7 @@ #ifndef GROUP_SESSION_BUILDER_H #define GROUP_SESSION_BUILDER_H -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { @@ -30,12 +30,12 @@ extern "C" { * When finished, free the returned instance by calling group_session_builder_free(). * * @param builder set to a freshly allocated group session builder instance - * @param store the axolotl_store_context to store all state information in + * @param store the signal_protocol_store_context to store all state information in * @param global_context the global library context * @return 0 on success, or negative on failure */ int group_session_builder_create(group_session_builder **builder, - axolotl_store_context *store, axolotl_context *global_context); + signal_protocol_store_context *store, signal_context *global_context); /** * Construct a group session for receiving messages from senderKeyName. @@ -46,7 +46,7 @@ int group_session_builder_create(group_session_builder **builder, * @return 0 on success, or negative on failure */ int group_session_builder_process_session(group_session_builder *builder, - const axolotl_sender_key_name *sender_key_name, + const signal_protocol_sender_key_name *sender_key_name, sender_key_distribution_message *distribution_message); /** @@ -59,7 +59,7 @@ int group_session_builder_process_session(group_session_builder *builder, */ int group_session_builder_create_session(group_session_builder *builder, sender_key_distribution_message **distribution_message, - const axolotl_sender_key_name *sender_key_name); + const signal_protocol_sender_key_name *sender_key_name); void group_session_builder_free(group_session_builder *builder); diff --git a/libs/libaxolotl/src/hkdf.c b/libs/libaxolotl/src/hkdf.c index 63b35ddaa4..d8df253c8b 100644 --- a/libs/libaxolotl/src/hkdf.c +++ b/libs/libaxolotl/src/hkdf.c @@ -6,7 +6,7 @@ #include <math.h> #include <assert.h> -#include "axolotl_internal.h" +#include "signal_protocol_internal.h" #define HASH_OUTPUT_SIZE 32 @@ -15,22 +15,22 @@ struct hkdf_context { - axolotl_type_base base; - axolotl_context *global_context; + signal_type_base base; + signal_context *global_context; int iteration_start_offset; }; -int hkdf_create(hkdf_context **context, int message_version, axolotl_context *global_context) +int hkdf_create(hkdf_context **context, int message_version, signal_context *global_context) { assert(global_context); *context = malloc(sizeof(hkdf_context)); if(!(*context)) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(*context, 0, sizeof(hkdf_context)); - AXOLOTL_INIT(*context, hkdf_destroy); + SIGNAL_INIT(*context, hkdf_destroy); (*context)->global_context = global_context; if(message_version == 2) { @@ -41,7 +41,7 @@ int hkdf_create(hkdf_context **context, int message_version, axolotl_context *gl } else { free(*context); - return AX_ERR_INVAL; + return SG_ERR_INVAL; } return 0; @@ -53,43 +53,43 @@ ssize_t hkdf_extract(hkdf_context *context, const uint8_t *input_key_material, size_t input_key_material_len) { int result = 0; - axolotl_buffer *mac_buffer = 0; + signal_buffer *mac_buffer = 0; uint8_t *mac = 0; size_t mac_len = 0; void *hmac_context; assert(context); - result = axolotl_hmac_sha256_init(context->global_context, + result = signal_hmac_sha256_init(context->global_context, &hmac_context, salt, salt_len); if(result < 0) { goto complete; } - result = axolotl_hmac_sha256_update(context->global_context, + result = signal_hmac_sha256_update(context->global_context, hmac_context, input_key_material, input_key_material_len); if(result < 0) { goto complete; } - result = axolotl_hmac_sha256_final(context->global_context, + result = signal_hmac_sha256_final(context->global_context, hmac_context, &mac_buffer); if(result < 0) { goto complete; } - mac_len = axolotl_buffer_len(mac_buffer); + mac_len = signal_buffer_len(mac_buffer); mac = malloc(mac_len); if(!mac) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - memcpy(mac, axolotl_buffer_data(mac_buffer), mac_len); + memcpy(mac, signal_buffer_data(mac_buffer), mac_len); complete: - axolotl_hmac_sha256_cleanup(context->global_context, hmac_context); - axolotl_buffer_free(mac_buffer); + signal_hmac_sha256_cleanup(context->global_context, hmac_context); + signal_buffer_free(mac_buffer); if(result >= 0) { *output = mac; @@ -108,7 +108,7 @@ ssize_t hkdf_expand(hkdf_context *context, { int iterations = (int)ceil((double)output_len / (double)HASH_OUTPUT_SIZE); size_t remaining_len = output_len; - axolotl_buffer *step_buffer = 0; + signal_buffer *step_buffer = 0; size_t step_size = 0; uint8_t *result_buf = 0; size_t result_buf_len = 0; @@ -119,66 +119,66 @@ ssize_t hkdf_expand(hkdf_context *context, assert(context); for(i = context->iteration_start_offset; i < iterations + context->iteration_start_offset; i++) { - result = axolotl_hmac_sha256_init(context->global_context, + result = signal_hmac_sha256_init(context->global_context, &hmac_context, prk, prk_len); if(result < 0) { goto complete; } if(step_buffer) { - result = axolotl_hmac_sha256_update(context->global_context, + result = signal_hmac_sha256_update(context->global_context, hmac_context, - axolotl_buffer_data(step_buffer), - axolotl_buffer_len(step_buffer)); + signal_buffer_data(step_buffer), + signal_buffer_len(step_buffer)); if(result < 0) { goto complete; } - axolotl_buffer_free(step_buffer); + signal_buffer_free(step_buffer); step_buffer = 0; } if(info) { - result = axolotl_hmac_sha256_update(context->global_context, + result = signal_hmac_sha256_update(context->global_context, hmac_context, info, info_len); if(result < 0) { goto complete; } } - result = axolotl_hmac_sha256_update(context->global_context, + result = signal_hmac_sha256_update(context->global_context, hmac_context, &i, sizeof(uint8_t)); if(result < 0) { goto complete; } - result = axolotl_hmac_sha256_final(context->global_context, + result = signal_hmac_sha256_final(context->global_context, hmac_context, &step_buffer); if(result < 0) { goto complete; } - axolotl_hmac_sha256_cleanup(context->global_context, hmac_context); + signal_hmac_sha256_cleanup(context->global_context, hmac_context); hmac_context = 0; - step_size = MIN(remaining_len, axolotl_buffer_len(step_buffer)); + step_size = MIN(remaining_len, signal_buffer_len(step_buffer)); if(!result_buf) { result_buf = malloc(step_size); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - memcpy(result_buf, axolotl_buffer_data(step_buffer), step_size); + memcpy(result_buf, signal_buffer_data(step_buffer), step_size); result_buf_len = step_size; } else { uint8_t *tmp_buf = realloc(result_buf, result_buf_len + step_size); if(!tmp_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } result_buf = tmp_buf; - memcpy(result_buf + result_buf_len, axolotl_buffer_data(step_buffer), step_size); + memcpy(result_buf + result_buf_len, signal_buffer_data(step_buffer), step_size); result_buf_len += step_size; } remaining_len -= step_size; @@ -186,9 +186,9 @@ ssize_t hkdf_expand(hkdf_context *context, complete: if(hmac_context) { - axolotl_hmac_sha256_cleanup(context->global_context, hmac_context); + signal_hmac_sha256_cleanup(context->global_context, hmac_context); } - axolotl_buffer_free(step_buffer); + signal_buffer_free(step_buffer); if(result < 0) { free(result_buf); return result; @@ -214,7 +214,7 @@ ssize_t hkdf_derive_secrets(hkdf_context *context, prk_len = hkdf_extract(context, &prk, salt, salt_len, input_key_material, input_key_material_len); if(prk_len < 0) { - axolotl_log(context->global_context, AX_LOG_ERROR, "hkdf_extract error: %d", prk_len); + signal_log(context->global_context, SG_LOG_ERROR, "hkdf_extract error: %d", prk_len); return prk_len; } @@ -249,7 +249,7 @@ int hkdf_compare(const hkdf_context *context1, const hkdf_context *context2) } } -void hkdf_destroy(axolotl_type_base *type) +void hkdf_destroy(signal_type_base *type) { hkdf_context *context = (hkdf_context *)type; free(context); diff --git a/libs/libaxolotl/src/hkdf.h b/libs/libaxolotl/src/hkdf.h index 8e939485c3..43ee870401 100644 --- a/libs/libaxolotl/src/hkdf.h +++ b/libs/libaxolotl/src/hkdf.h @@ -3,13 +3,13 @@ #include <stdint.h> #include <stddef.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { #endif -int hkdf_create(hkdf_context **context, int message_version, axolotl_context *global_context); +int hkdf_create(hkdf_context **context, int message_version, signal_context *global_context); ssize_t hkdf_derive_secrets(hkdf_context *context, uint8_t **output, @@ -20,7 +20,7 @@ ssize_t hkdf_derive_secrets(hkdf_context *context, int hkdf_compare(const hkdf_context *context1, const hkdf_context *context2); -void hkdf_destroy(axolotl_type_base *type); +void hkdf_destroy(signal_type_base *type); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/key_helper.c b/libs/libaxolotl/src/key_helper.c index a1403a517f..80deb6ab08 100644 --- a/libs/libaxolotl/src/key_helper.c +++ b/libs/libaxolotl/src/key_helper.c @@ -2,19 +2,19 @@ #include <assert.h> -#include "axolotl_internal.h" #include "session_pre_key.h" #include "ratchet.h" #include "curve.h" +#include "signal_protocol_internal.h" #include "utlist.h" -struct axolotl_key_helper_pre_key_list_node +struct signal_protocol_key_helper_pre_key_list_node { session_pre_key *element; - struct axolotl_key_helper_pre_key_list_node *next; + struct signal_protocol_key_helper_pre_key_list_node *next; }; -int axolotl_key_helper_generate_identity_key_pair(ratchet_identity_key_pair **key_pair, axolotl_context *global_context) +int signal_protocol_key_helper_generate_identity_key_pair(ratchet_identity_key_pair **key_pair, signal_context *global_context) { int result = 0; ratchet_identity_key_pair *result_pair = 0; @@ -39,11 +39,11 @@ complete: if(result >= 0) { *key_pair = result_pair; } - AXOLOTL_UNREF(ec_pair); + SIGNAL_UNREF(ec_pair); return result; } -int axolotl_key_helper_generate_registration_id(uint32_t *registration_id, int extended_range, axolotl_context *global_context) +int signal_protocol_key_helper_generate_registration_id(uint32_t *registration_id, int extended_range, signal_context *global_context) { uint32_t range; uint32_t id_value; @@ -59,7 +59,7 @@ int axolotl_key_helper_generate_registration_id(uint32_t *registration_id, int e range = INT32_MAX - 1; } else { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } result = global_context->crypto_provider.random_func( @@ -76,7 +76,7 @@ int axolotl_key_helper_generate_registration_id(uint32_t *registration_id, int e return 0; } -int axolotl_key_helper_get_random_sequence(int *value, int max, axolotl_context *global_context) +int signal_protocol_key_helper_get_random_sequence(int *value, int max, signal_context *global_context) { int result = 0; int32_t result_value; @@ -98,16 +98,16 @@ int axolotl_key_helper_get_random_sequence(int *value, int max, axolotl_context return 0; } -int axolotl_key_helper_generate_pre_keys(axolotl_key_helper_pre_key_list_node **head, +int signal_protocol_key_helper_generate_pre_keys(signal_protocol_key_helper_pre_key_list_node **head, unsigned int start, unsigned int count, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; ec_key_pair *ec_pair = 0; session_pre_key *pre_key = 0; - axolotl_key_helper_pre_key_list_node *result_head = 0; - axolotl_key_helper_pre_key_list_node *cur_node = 0; - axolotl_key_helper_pre_key_list_node *node = 0; + signal_protocol_key_helper_pre_key_list_node *result_head = 0; + signal_protocol_key_helper_pre_key_list_node *cur_node = 0; + signal_protocol_key_helper_pre_key_list_node *node = 0; unsigned int start_index = start - 1; unsigned int i; @@ -127,12 +127,12 @@ int axolotl_key_helper_generate_pre_keys(axolotl_key_helper_pre_key_list_node ** goto complete; } - AXOLOTL_UNREF(ec_pair); + SIGNAL_UNREF(ec_pair); ec_pair = 0; - node = malloc(sizeof(axolotl_key_helper_pre_key_list_node)); + node = malloc(sizeof(signal_protocol_key_helper_pre_key_list_node)); if(!node) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } node->element = pre_key; @@ -151,20 +151,20 @@ int axolotl_key_helper_generate_pre_keys(axolotl_key_helper_pre_key_list_node ** complete: if(ec_pair) { - AXOLOTL_UNREF(ec_pair); + SIGNAL_UNREF(ec_pair); } if(pre_key) { - AXOLOTL_UNREF(pre_key); + SIGNAL_UNREF(pre_key); } if(node) { free(node); } if(result < 0) { if(result_head) { - axolotl_key_helper_pre_key_list_node *tmp_node; + signal_protocol_key_helper_pre_key_list_node *tmp_node; LL_FOREACH_SAFE(result_head, cur_node, tmp_node) { LL_DELETE(result_head, cur_node); - AXOLOTL_UNREF(cur_node->element); + SIGNAL_UNREF(cur_node->element); free(cur_node); } } @@ -175,33 +175,33 @@ complete: return result; } -session_pre_key *axolotl_key_helper_key_list_element(const axolotl_key_helper_pre_key_list_node *node) +session_pre_key *signal_protocol_key_helper_key_list_element(const signal_protocol_key_helper_pre_key_list_node *node) { assert(node); assert(node->element); return node->element; } -axolotl_key_helper_pre_key_list_node *axolotl_key_helper_key_list_next(const axolotl_key_helper_pre_key_list_node *node) +signal_protocol_key_helper_pre_key_list_node *signal_protocol_key_helper_key_list_next(const signal_protocol_key_helper_pre_key_list_node *node) { assert(node); return node->next; } -void axolotl_key_helper_key_list_free(axolotl_key_helper_pre_key_list_node *head) +void signal_protocol_key_helper_key_list_free(signal_protocol_key_helper_pre_key_list_node *head) { if(head) { - axolotl_key_helper_pre_key_list_node *cur_node; - axolotl_key_helper_pre_key_list_node *tmp_node; + signal_protocol_key_helper_pre_key_list_node *cur_node; + signal_protocol_key_helper_pre_key_list_node *tmp_node; LL_FOREACH_SAFE(head, cur_node, tmp_node) { LL_DELETE(head, cur_node); - AXOLOTL_UNREF(cur_node->element); + SIGNAL_UNREF(cur_node->element); free(cur_node); } } } -int axolotl_key_helper_generate_last_resort_pre_key(session_pre_key **pre_key, axolotl_context *global_context) +int signal_protocol_key_helper_generate_last_resort_pre_key(session_pre_key **pre_key, signal_context *global_context) { int result = 0; session_pre_key *result_pre_key = 0; @@ -217,24 +217,24 @@ int axolotl_key_helper_generate_last_resort_pre_key(session_pre_key **pre_key, a result = session_pre_key_create(&result_pre_key, PRE_KEY_MEDIUM_MAX_VALUE, ec_pair); complete: - AXOLOTL_UNREF(ec_pair); + SIGNAL_UNREF(ec_pair); if(result >= 0) { *pre_key = result_pre_key; } return result; } -int axolotl_key_helper_generate_signed_pre_key(session_signed_pre_key **signed_pre_key, +int signal_protocol_key_helper_generate_signed_pre_key(session_signed_pre_key **signed_pre_key, const ratchet_identity_key_pair *identity_key_pair, uint32_t signed_pre_key_id, uint64_t timestamp, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; session_signed_pre_key *result_signed_pre_key = 0; ec_key_pair *ec_pair = 0; - axolotl_buffer *public_buf = 0; - axolotl_buffer *signature_buf = 0; + signal_buffer *public_buf = 0; + signal_buffer *signature_buf = 0; ec_public_key *public_key = 0; ec_private_key *private_key = 0; @@ -256,28 +256,28 @@ int axolotl_key_helper_generate_signed_pre_key(session_signed_pre_key **signed_p result = curve_calculate_signature(global_context, &signature_buf, private_key, - axolotl_buffer_data(public_buf), - axolotl_buffer_len(public_buf)); + signal_buffer_data(public_buf), + signal_buffer_len(public_buf)); if(result < 0) { goto complete; } result = session_signed_pre_key_create(&result_signed_pre_key, signed_pre_key_id, timestamp, ec_pair, - axolotl_buffer_data(signature_buf), - axolotl_buffer_len(signature_buf)); + signal_buffer_data(signature_buf), + signal_buffer_len(signature_buf)); complete: - AXOLOTL_UNREF(ec_pair); - axolotl_buffer_free(public_buf); - axolotl_buffer_free(signature_buf); + SIGNAL_UNREF(ec_pair); + signal_buffer_free(public_buf); + signal_buffer_free(signature_buf); if(result >= 0) { *signed_pre_key = result_signed_pre_key; } return result; } -int axolotl_key_helper_generate_sender_signing_key(ec_key_pair **key_pair, axolotl_context *global_context) +int signal_protocol_key_helper_generate_sender_signing_key(ec_key_pair **key_pair, signal_context *global_context) { int result; @@ -288,26 +288,26 @@ int axolotl_key_helper_generate_sender_signing_key(ec_key_pair **key_pair, axolo return result; } -int axolotl_key_helper_generate_sender_key(axolotl_buffer **key_buffer, axolotl_context *global_context) +int signal_protocol_key_helper_generate_sender_key(signal_buffer **key_buffer, signal_context *global_context) { int result = 0; - axolotl_buffer *result_buffer = 0; + signal_buffer *result_buffer = 0; assert(global_context); - result_buffer = axolotl_buffer_alloc(32); + result_buffer = signal_buffer_alloc(32); if(!result_buffer) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - result = axolotl_crypto_random(global_context, - axolotl_buffer_data(result_buffer), - axolotl_buffer_len(result_buffer)); + result = signal_crypto_random(global_context, + signal_buffer_data(result_buffer), + signal_buffer_len(result_buffer)); complete: if(result < 0) { - axolotl_buffer_free(result_buffer); + signal_buffer_free(result_buffer); } else { *key_buffer = result_buffer; @@ -316,12 +316,12 @@ complete: return result; } -int axolotl_key_helper_generate_sender_key_id(uint32_t *key_id, axolotl_context *global_context) +int signal_protocol_key_helper_generate_sender_key_id(uint32_t *key_id, signal_context *global_context) { int result; int value; - result = axolotl_key_helper_get_random_sequence(&value, INT32_MAX, global_context); + result = signal_protocol_key_helper_get_random_sequence(&value, INT32_MAX, global_context); if(result >= 0) { *key_id = (uint32_t)value; diff --git a/libs/libaxolotl/src/key_helper.h b/libs/libaxolotl/src/key_helper.h index 1a7175b620..be3ef8429f 100644 --- a/libs/libaxolotl/src/key_helper.h +++ b/libs/libaxolotl/src/key_helper.h @@ -2,7 +2,7 @@ #define KEY_HELPER_H #include <stdint.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { @@ -15,7 +15,7 @@ extern "C" { * @param key_pair the generated identity key pair * @return 0 on success, or negative on failure */ -int axolotl_key_helper_generate_identity_key_pair(ratchet_identity_key_pair **key_pair, axolotl_context *global_context); +int signal_protocol_key_helper_generate_identity_key_pair(ratchet_identity_key_pair **key_pair, signal_context *global_context); /** * Generate a registration ID. Clients should only do this once, @@ -29,7 +29,7 @@ int axolotl_key_helper_generate_identity_key_pair(ratchet_identity_key_pair **ke * higher encoding overhead. * @return 0 on success, or negative on failure */ -int axolotl_key_helper_generate_registration_id(uint32_t *registration_id, int extended_range, axolotl_context *global_context); +int signal_protocol_key_helper_generate_registration_id(uint32_t *registration_id, int extended_range, signal_context *global_context); /** * Generate a random number bounded by the provided maximum @@ -38,7 +38,7 @@ int axolotl_key_helper_generate_registration_id(uint32_t *registration_id, int e * @param max the maximum value of the random number * @return 0 on success, or negative on failure */ -int axolotl_key_helper_get_random_sequence(int *value, int max, axolotl_context *global_context); +int signal_protocol_key_helper_get_random_sequence(int *value, int max, signal_context *global_context); /** * Generate a list of PreKeys. Clients should do this at install time, and @@ -49,16 +49,16 @@ int axolotl_key_helper_get_random_sequence(int *value, int max, axolotl_context * as possible. * * When finished with this list, the caller should free it by calling - * axolotl_key_helper_key_list_free(). + * signal_protocol_key_helper_key_list_free(). * * @param head pointer to the head of the key list * @param start the starting pre key ID, inclusive. * @param count the number of pre keys to generate. * @return 0 on success, or negative on failure */ -int axolotl_key_helper_generate_pre_keys(axolotl_key_helper_pre_key_list_node **head, +int signal_protocol_key_helper_generate_pre_keys(signal_protocol_key_helper_pre_key_list_node **head, unsigned int start, unsigned int count, - axolotl_context *global_context); + signal_context *global_context); /** * Get the pre key element for the current node in the key list. @@ -66,22 +66,22 @@ int axolotl_key_helper_generate_pre_keys(axolotl_key_helper_pre_key_list_node ** * @param current list node * @return pre key element */ -session_pre_key *axolotl_key_helper_key_list_element(const axolotl_key_helper_pre_key_list_node *node); +session_pre_key *signal_protocol_key_helper_key_list_element(const signal_protocol_key_helper_pre_key_list_node *node); /** - * Get the next element in the ket list. + * Get the next element in the key list. * * @param current list node * @return next list node, or 0 if at the end of the list */ -axolotl_key_helper_pre_key_list_node *axolotl_key_helper_key_list_next(const axolotl_key_helper_pre_key_list_node *node); +signal_protocol_key_helper_pre_key_list_node *signal_protocol_key_helper_key_list_next(const signal_protocol_key_helper_pre_key_list_node *node); /** * Free the key list. * * @param head pointer to the head of the list to free */ -void axolotl_key_helper_key_list_free(axolotl_key_helper_pre_key_list_node *head); +void signal_protocol_key_helper_key_list_free(signal_protocol_key_helper_pre_key_list_node *head); /** * Generate the last resort pre key. Clients should do this only once, at @@ -90,7 +90,7 @@ void axolotl_key_helper_key_list_free(axolotl_key_helper_pre_key_list_node *head * @param pre_key set to the generated pre key * @return 0 on success, or negative on failure */ -int axolotl_key_helper_generate_last_resort_pre_key(session_pre_key **pre_key, axolotl_context *global_context); +int signal_protocol_key_helper_generate_last_resort_pre_key(session_pre_key **pre_key, signal_context *global_context); /** * Generate a signed pre key @@ -102,11 +102,11 @@ int axolotl_key_helper_generate_last_resort_pre_key(session_pre_key **pre_key, a * * @return 0 on success, or negative on failure */ -int axolotl_key_helper_generate_signed_pre_key(session_signed_pre_key **signed_pre_key, +int signal_protocol_key_helper_generate_signed_pre_key(session_signed_pre_key **signed_pre_key, const ratchet_identity_key_pair *identity_key_pair, uint32_t signed_pre_key_id, uint64_t timestamp, - axolotl_context *global_context); + signal_context *global_context); /* * Generate a sender signing key pair @@ -114,7 +114,7 @@ int axolotl_key_helper_generate_signed_pre_key(session_signed_pre_key **signed_p * @param key_pair the generated key pair * @return 0 on success, or negative on failure */ -int axolotl_key_helper_generate_sender_signing_key(ec_key_pair **key_pair, axolotl_context *global_context); +int signal_protocol_key_helper_generate_sender_signing_key(ec_key_pair **key_pair, signal_context *global_context); /* * Generate a sender key @@ -122,7 +122,7 @@ int axolotl_key_helper_generate_sender_signing_key(ec_key_pair **key_pair, axolo * @param key_buffer buffer to be allocated and populated with the result * @return 0 on success, or negative on failure */ -int axolotl_key_helper_generate_sender_key(axolotl_buffer **key_buffer, axolotl_context *global_context); +int signal_protocol_key_helper_generate_sender_key(signal_buffer **key_buffer, signal_context *global_context); /* * Generate a sender key ID @@ -130,7 +130,7 @@ int axolotl_key_helper_generate_sender_key(axolotl_buffer **key_buffer, axolotl_ * @param key_id assigned to the generated ID * @return 0 on success, or negative on failure */ -int axolotl_key_helper_generate_sender_key_id(uint32_t *key_id, axolotl_context *global_context); +int signal_protocol_key_helper_generate_sender_key_id(uint32_t *key_id, signal_context *global_context); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/protobuf-c/CMakeLists.txt b/libs/libaxolotl/src/protobuf-c/CMakeLists.txt index 63f18db8ae..1af25df194 100644 --- a/libs/libaxolotl/src/protobuf-c/CMakeLists.txt +++ b/libs/libaxolotl/src/protobuf-c/CMakeLists.txt @@ -3,7 +3,10 @@ IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") ENDIF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") IF(CMAKE_COMPILER_IS_GNUCC) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-compare -Wno-sign-conversion") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-compare") + IF(GCC_WARN_SIGN_CONVERSION) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-conversion") + ENDIF(GCC_WARN_SIGN_CONVERSION) ENDIF(CMAKE_COMPILER_IS_GNUCC) IF(CMAKE_C_COMPILER_ID MATCHES "Clang") @@ -15,3 +18,8 @@ set(protobuf_SRCS ) add_library(protobuf-c OBJECT ${protobuf_SRCS}) + +# Add -fPIC flag +if(BUILD_SHARED_LIBS) + set_property(TARGET protobuf-c PROPERTY POSITION_INDEPENDENT_CODE ON) +endif() diff --git a/libs/libaxolotl/src/protobuf-c/protobuf-c.c b/libs/libaxolotl/src/protobuf-c/protobuf-c.c index 4c1438b44a..4f2f5bcc73 100644 --- a/libs/libaxolotl/src/protobuf-c/protobuf-c.c +++ b/libs/libaxolotl/src/protobuf-c/protobuf-c.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2014, Dave Benson and the protobuf-c authors. + * Copyright (c) 2008-2015, Dave Benson and the protobuf-c authors. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,15 +50,16 @@ #include "protobuf-c.h" -#if defined(_MSC_VER) && !defined(__cplusplus) -#define inline __inline -#endif - #define TRUE 1 #define FALSE 0 #define PROTOBUF_C__ASSERT_NOT_REACHED() assert(0) +/* Workaround for Microsoft compilers. */ +#ifdef _MSC_VER +# define inline __inline +#endif + /** * \defgroup internal Internal functions and macros * @@ -460,6 +461,39 @@ required_field_get_packed_size(const ProtobufCFieldDescriptor *field, } /** + * Calculate the serialized size of a single oneof message field, including + * the space needed by the preceding tag. Returns 0 if the oneof field isn't + * selected or is not set. + * + * \param field + * Field descriptor for member. + * \param oneof_case + * A pointer to the case enum that selects the field in the oneof. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t +oneof_field_get_packed_size(const ProtobufCFieldDescriptor *field, + const uint32_t *oneof_case, + const void *member) +{ + if (*oneof_case == field->id) { + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void * const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } + } else { + return 0; + } + return required_field_get_packed_size(field, member); +} + +/** * Calculate the serialized size of a single optional message field, including * the space needed by the preceding tag. Returns 0 if the optional field isn't * set. @@ -620,7 +654,10 @@ size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message) if (field->label == PROTOBUF_C_LABEL_REQUIRED) { rv += required_field_get_packed_size(field, member); } else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) { - rv += optional_field_get_packed_size(field, qmember, member); + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) + rv += oneof_field_get_packed_size(field, qmember, member); + else + rv += optional_field_get_packed_size(field, qmember, member); } else { rv += repeated_field_get_packed_size( field, @@ -1018,6 +1055,40 @@ required_field_pack(const ProtobufCFieldDescriptor *field, } /** + * Pack a oneof field and return the number of bytes written. Only packs the + * field that is selected by the case enum. + * + * \param field + * Field descriptor. + * \param oneof_case + * A pointer to the case enum that selects the field in the oneof. + * \param member + * The field member. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static size_t +oneof_field_pack(const ProtobufCFieldDescriptor *field, + const uint32_t *oneof_case, + const void *member, uint8_t *out) +{ + if (*oneof_case == field->id) { + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void * const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } + } else { + return 0; + } + return required_field_pack(field, member, out); +} + +/** * Pack an optional field and return the number of bytes written. * * \param field @@ -1311,6 +1382,7 @@ protobuf_c_message_pack(const ProtobufCMessage *message, uint8_t *out) * quantifier field of the structure), but the pointer is only * valid if the field is: * - a repeated field, or + * - a field that is part of a oneof * - an optional field that isn't a pointer type * (Meaning: not a message or a string). */ @@ -1320,11 +1392,10 @@ protobuf_c_message_pack(const ProtobufCMessage *message, uint8_t *out) if (field->label == PROTOBUF_C_LABEL_REQUIRED) { rv += required_field_pack(field, member, out + rv); } else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) { - /* - * Note that qmember is bogus for strings and messages, - * but it isn't used. - */ - rv += optional_field_pack(field, qmember, member, out + rv); + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) + rv += oneof_field_pack (field, qmember, member, out + rv); + else + rv += optional_field_pack(field, qmember, member, out + rv); } else { rv += repeated_field_pack(field, *(const size_t *) qmember, member, out + rv); @@ -1459,6 +1530,39 @@ required_field_pack_to_buffer(const ProtobufCFieldDescriptor *field, } /** + * Pack a oneof field to a buffer. Only packs the field that is selected by the case enum. + * + * \param field + * Field descriptor. + * \param oneof_case + * A pointer to the case enum that selects the field in the oneof. + * \param member + * The element to be packed. + * \param[out] buffer + * Virtual buffer to append data to. + * \return + * Number of bytes serialised to `buffer`. + */ +static size_t +oneof_field_pack_to_buffer(const ProtobufCFieldDescriptor *field, + const uint32_t *oneof_case, + const void *member, ProtobufCBuffer *buffer) +{ + if (*oneof_case == field->id) { + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void *const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } + } else { + return 0; + } + return required_field_pack_to_buffer(field, member, buffer); +} + +/** * Pack an optional field to a buffer. * * \param field @@ -1734,12 +1838,21 @@ protobuf_c_message_pack_to_buffer(const ProtobufCMessage *message, if (field->label == PROTOBUF_C_LABEL_REQUIRED) { rv += required_field_pack_to_buffer(field, member, buffer); } else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) { - rv += optional_field_pack_to_buffer( - field, - qmember, - member, - buffer - ); + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) { + rv += oneof_field_pack_to_buffer( + field, + qmember, + member, + buffer + ); + } else { + rv += optional_field_pack_to_buffer( + field, + qmember, + member, + buffer + ); + } } else { rv += repeated_field_pack_to_buffer( field, @@ -1909,7 +2022,7 @@ merge_messages(ProtobufCMessage *earlier_msg, { unsigned i; const ProtobufCFieldDescriptor *fields = - earlier_msg->descriptor->fields; + latter_msg->descriptor->fields; for (i = 0; i < latter_msg->descriptor->n_fields; i++) { if (fields[i].label == PROTOBUF_C_LABEL_REPEATED) { size_t *n_earlier = @@ -1957,38 +2070,65 @@ merge_messages(ProtobufCMessage *earlier_msg, *n_earlier = 0; *p_earlier = 0; } - } else if (fields[i].type == PROTOBUF_C_TYPE_MESSAGE) { - ProtobufCMessage **em = - STRUCT_MEMBER_PTR(ProtobufCMessage *, - earlier_msg, - fields[i].offset); - ProtobufCMessage **lm = - STRUCT_MEMBER_PTR(ProtobufCMessage *, - latter_msg, - fields[i].offset); - if (*em != NULL) { - if (*lm != NULL) { - if (!merge_messages - (*em, *lm, allocator)) - return FALSE; + } else if (fields[i].label == PROTOBUF_C_LABEL_OPTIONAL) { + const ProtobufCFieldDescriptor *field; + uint32_t *earlier_case_p = STRUCT_MEMBER_PTR(uint32_t, + earlier_msg, + fields[i]. + quantifier_offset); + uint32_t *latter_case_p = STRUCT_MEMBER_PTR(uint32_t, + latter_msg, + fields[i]. + quantifier_offset); + protobuf_c_boolean need_to_merge = FALSE; + void *earlier_elem; + void *latter_elem; + const void *def_val; + + if (fields[i].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) { + if (*latter_case_p == 0) { + /* lookup correct oneof field */ + int field_index = + int_range_lookup( + latter_msg->descriptor + ->n_field_ranges, + latter_msg->descriptor + ->field_ranges, + *earlier_case_p); + field = latter_msg->descriptor->fields + + field_index; } else { - /* Zero copy the optional message */ - assert(fields[i].label == - PROTOBUF_C_LABEL_OPTIONAL); - *lm = *em; - *em = NULL; + /* Oneof is present in the latter message, move on */ + continue; } + } else { + field = &fields[i]; } - } else if (fields[i].label == PROTOBUF_C_LABEL_OPTIONAL) { - size_t el_size = 0; - protobuf_c_boolean need_to_merge = FALSE; - void *earlier_elem = - STRUCT_MEMBER_P(earlier_msg, fields[i].offset); - void *latter_elem = - STRUCT_MEMBER_P(latter_msg, fields[i].offset); - const void *def_val = fields[i].default_value; - switch (fields[i].type) { + + earlier_elem = + STRUCT_MEMBER_P(earlier_msg, field->offset); + latter_elem = + STRUCT_MEMBER_P(latter_msg, field->offset); + def_val = field->default_value; + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: { + ProtobufCMessage *em = *(ProtobufCMessage **) earlier_elem; + ProtobufCMessage *lm = *(ProtobufCMessage **) latter_elem; + if (em != NULL) { + if (lm != NULL) { + if (!merge_messages(em, lm, allocator)) + return FALSE; + /* Already merged */ + need_to_merge = FALSE; + } else { + /* Zero copy the message */ + need_to_merge = TRUE; + } + } + break; + } case PROTOBUF_C_TYPE_BYTES: { uint8_t *e_data = ((ProtobufCBinaryData *) earlier_elem)->data; @@ -1996,11 +2136,10 @@ merge_messages(ProtobufCMessage *earlier_msg, ((ProtobufCBinaryData *) latter_elem)->data; const ProtobufCBinaryData *d_bd = (ProtobufCBinaryData *) def_val; - el_size = sizeof(ProtobufCBinaryData); need_to_merge = (e_data != NULL && - (d_bd != NULL && + (d_bd == NULL || e_data != d_bd->data)) && (l_data == NULL || (d_bd != NULL && @@ -2011,26 +2150,23 @@ merge_messages(ProtobufCMessage *earlier_msg, char *e_str = *(char **) earlier_elem; char *l_str = *(char **) latter_elem; const char *d_str = def_val; - el_size = sizeof(char *); need_to_merge = e_str != d_str && l_str == d_str; break; } default: { - el_size = sizeof_elt_in_repeated_array(fields[i].type); - - need_to_merge = - STRUCT_MEMBER(protobuf_c_boolean, - earlier_msg, - fields[i].quantifier_offset) && - !STRUCT_MEMBER(protobuf_c_boolean, - latter_msg, - fields[i].quantifier_offset); + /* Could be has field or case enum, the logic is + * equivalent, since 0 (FALSE) means not set for + * oneof */ + need_to_merge = (*earlier_case_p != 0) && + (*latter_case_p == 0); break; } } if (need_to_merge) { + size_t el_size = + sizeof_elt_in_repeated_array(field->type); memcpy(latter_elem, earlier_elem, el_size); /* * Reset the element from the old message to 0 @@ -2041,16 +2177,11 @@ merge_messages(ProtobufCMessage *earlier_msg, */ memset(earlier_elem, 0, el_size); - if (fields[i].quantifier_offset != 0) { - /* Set the has field, if applicable */ - STRUCT_MEMBER(protobuf_c_boolean, - latter_msg, - fields[i]. - quantifier_offset) = TRUE; - STRUCT_MEMBER(protobuf_c_boolean, - earlier_msg, - fields[i]. - quantifier_offset) = FALSE; + if (field->quantifier_offset != 0) { + /* Set the has field or the case enum, + * if applicable */ + *latter_case_p = *earlier_case_p; + *earlier_case_p = 0; } } } @@ -2349,6 +2480,66 @@ parse_required_member(ScannedMember *scanned_member, } static protobuf_c_boolean +parse_oneof_member (ScannedMember *scanned_member, + void *member, + ProtobufCMessage *message, + ProtobufCAllocator *allocator) +{ + uint32_t *oneof_case = STRUCT_MEMBER_PTR(uint32_t, message, + scanned_member->field->quantifier_offset); + + /* If we have already parsed a member of this oneof, free it. */ + if (*oneof_case != 0) { + /* lookup field */ + int field_index = + int_range_lookup(message->descriptor->n_field_ranges, + message->descriptor->field_ranges, + *oneof_case); + const ProtobufCFieldDescriptor *old_field = + message->descriptor->fields + field_index; + size_t el_size; + + switch (old_field->type) { + case PROTOBUF_C_TYPE_STRING: { + char **pstr = member; + const char *def = old_field->default_value; + if (*pstr != NULL && *pstr != def) + do_free(allocator, *pstr); + break; + } + case PROTOBUF_C_TYPE_BYTES: { + ProtobufCBinaryData *bd = member; + const ProtobufCBinaryData *def_bd = old_field->default_value; + if (bd->data != NULL && + (def_bd == NULL || bd->data != def_bd->data)) + { + do_free(allocator, bd->data); + } + break; + } + case PROTOBUF_C_TYPE_MESSAGE: { + ProtobufCMessage **pmessage = member; + const ProtobufCMessage *def_mess = old_field->default_value; + if (*pmessage != NULL && *pmessage != def_mess) + protobuf_c_message_free_unpacked(*pmessage, allocator); + break; + } + default: + break; + } + + el_size = sizeof_elt_in_repeated_array(old_field->type); + memset (member, 0, el_size); + } + if (!parse_required_member (scanned_member, member, allocator, TRUE)) + return FALSE; + + *oneof_case = scanned_member->tag; + return TRUE; +} + + +static protobuf_c_boolean parse_optional_member(ScannedMember *scanned_member, void *member, ProtobufCMessage *message, @@ -2561,8 +2752,13 @@ parse_member(ScannedMember *scanned_member, return parse_required_member(scanned_member, member, allocator, TRUE); case PROTOBUF_C_LABEL_OPTIONAL: - return parse_optional_member(scanned_member, member, - message, allocator); + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) { + return parse_oneof_member(scanned_member, member, + message, allocator); + } else { + return parse_optional_member(scanned_member, member, + message, allocator); + } case PROTOBUF_C_LABEL_REPEATED: if (scanned_member->wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED && @@ -2747,9 +2943,9 @@ protobuf_c_message_unpack(const ProtobufCMessageDescriptor *desc, goto error_cleanup_during_scan; } /* - * \todo Consider optimizing for field[1].id == tag, if field[1] - * exists! - */ + * \todo Consider optimizing for field[1].id == tag, if field[1] + * exists! + */ if (last_field == NULL || last_field->id != tag) { /* lookup field */ int field_index = @@ -2969,14 +3165,28 @@ void protobuf_c_message_free_unpacked(ProtobufCMessage *message, ProtobufCAllocator *allocator) { - const ProtobufCMessageDescriptor *desc = message->descriptor; + const ProtobufCMessageDescriptor *desc; unsigned f; + + if (message == NULL) + return; + desc = message->descriptor; + ASSERT_IS_MESSAGE(message); + if (allocator == NULL) allocator = &protobuf_c__allocator; message->descriptor = NULL; for (f = 0; f < desc->n_fields; f++) { + if (0 != (desc->fields[f].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) && + desc->fields[f].id != + STRUCT_MEMBER(uint32_t, message, desc->fields[f].quantifier_offset)) + { + /* This is not the selected oneof, skip it */ + continue; + } + if (desc->fields[f].label == PROTOBUF_C_LABEL_REPEATED) { size_t n = STRUCT_MEMBER(size_t, message, @@ -2985,24 +3195,25 @@ protobuf_c_message_free_unpacked(ProtobufCMessage *message, message, desc->fields[f].offset); - if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { - unsigned i; - for (i = 0; i < n; i++) - do_free(allocator, ((char **) arr)[i]); - } else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) { - unsigned i; - for (i = 0; i < n; i++) - do_free(allocator, ((ProtobufCBinaryData *) arr)[i].data); - } else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) { - unsigned i; - for (i = 0; i < n; i++) - protobuf_c_message_free_unpacked( - ((ProtobufCMessage **) arr)[i], - allocator - ); - } - if (arr != NULL) + if (arr != NULL) { + if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { + unsigned i; + for (i = 0; i < n; i++) + do_free(allocator, ((char **) arr)[i]); + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) { + unsigned i; + for (i = 0; i < n; i++) + do_free(allocator, ((ProtobufCBinaryData *) arr)[i].data); + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) { + unsigned i; + for (i = 0; i < n; i++) + protobuf_c_message_free_unpacked( + ((ProtobufCMessage **) arr)[i], + allocator + ); + } do_free(allocator, arr); + } } else if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { char *str = STRUCT_MEMBER(char *, message, desc->fields[f].offset); @@ -3049,9 +3260,8 @@ protobuf_c_message_init(const ProtobufCMessageDescriptor * descriptor, protobuf_c_boolean protobuf_c_message_check(const ProtobufCMessage *message) { - unsigned i; - - if (!message || + unsigned i; + if (!message || !message->descriptor || message->descriptor->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { diff --git a/libs/libaxolotl/src/protobuf-c/protobuf-c.h b/libs/libaxolotl/src/protobuf-c/protobuf-c.h index 55156a0510..705a1f7003 100644 --- a/libs/libaxolotl/src/protobuf-c/protobuf-c.h +++ b/libs/libaxolotl/src/protobuf-c/protobuf-c.h @@ -106,9 +106,25 @@ extern const ProtobufCMessageDescriptor foo__bar__baz_bah__descriptor; * sufficient to allow them to be cast to `ProtobufCMessage`. * * For each message defined in a `.proto` file, we generate a number of - * functions. Each function name contains a prefix based on the package name and - * message name in order to make it a unique C identifier. + * functions and macros. Each function name contains a prefix based on the + * package name and message name in order to make it a unique C identifier. * + * - `INIT`. Statically initializes a message object, initializing its + * descriptor and setting its fields to default values. Uninitialized + * messages cannot be processed by the protobuf-c library. + * +~~~{.c} +#define FOO__BAR__BAZ_BAH__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&foo__bar__baz_bah__descriptor), 0 } +~~~ + * - `init()`. Initializes a message object, initializing its descriptor and + * setting its fields to default values. Uninitialized messages cannot be + * processed by the protobuf-c library. + * +~~~{.c} +void foo__bar__baz_bah__init + (Foo__Bar__BazBah *message); +~~~ * - `unpack()`. Unpacks data for a particular message format. Note that the * `allocator` parameter is usually `NULL` to indicate that the system's * `malloc()` and `free()` functions should be used for dynamically allocating @@ -205,10 +221,9 @@ PROTOBUF_C__BEGIN_DECLS # define PROTOBUF_C__API #endif -#if !defined(PROTOBUF_C__NO_DEPRECATED) -# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -# define PROTOBUF_C__DEPRECATED __attribute__((__deprecated__)) -# endif +#if !defined(PROTOBUF_C__NO_DEPRECATED) && \ + ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +# define PROTOBUF_C__DEPRECATED __attribute__((__deprecated__)) #else # define PROTOBUF_C__DEPRECATED #endif @@ -240,6 +255,9 @@ typedef enum { /** Set if the field is marked with the `deprecated` option. */ PROTOBUF_C_FIELD_FLAG_DEPRECATED = (1 << 1), + + /** Set if the field is a member of a oneof (union). */ + PROTOBUF_C_FIELD_FLAG_ONEOF = (1 << 2), } ProtobufCFieldFlag; /** @@ -546,7 +564,7 @@ struct ProtobufCFieldDescriptor { /** * The offset in bytes of the message's C structure's quantifier field * (the `has_MEMBER` field for optional members or the `n_MEMBER` field - * for repeated members. + * for repeated members or the case enum for oneofs). */ unsigned quantifier_offset; @@ -763,13 +781,13 @@ protobuf_c_version_number(void); * The version of the protobuf-c headers, represented as a string using the same * format as protobuf_c_version(). */ -#define PROTOBUF_C_VERSION "1.0.1" +#define PROTOBUF_C_VERSION "1.1.1" /** * The version of the protobuf-c headers, represented as an integer using the * same format as protobuf_c_version_number(). */ -#define PROTOBUF_C_VERSION_NUMBER 1000001 +#define PROTOBUF_C_VERSION_NUMBER 1001001 /** * The minimum protoc-c version which works with the current version of the diff --git a/libs/libaxolotl/src/protocol.c b/libs/libaxolotl/src/protocol.c index 5d29a5b138..9c8ce54c8f 100644 --- a/libs/libaxolotl/src/protocol.c +++ b/libs/libaxolotl/src/protocol.c @@ -3,50 +3,32 @@ #include <string.h> #include <assert.h> -#include "axolotl_internal.h" #include "curve.h" +#include "signal_protocol_internal.h" #include "WhisperTextProtocol.pb-c.h" -#define WHISPER_MESSAGE_MAC_LENGTH 8 +#define SIGNAL_MESSAGE_MAC_LENGTH 8 #define SIGNATURE_LENGTH 64 -struct key_exchange_message -{ - axolotl_type_base base; - - uint8_t version; - uint8_t supported_version; - uint32_t sequence; - uint32_t flags; - - ec_public_key *base_key; - uint8_t base_key_signature[CURVE_SIGNATURE_LEN]; - - ec_public_key *ratchet_key; - ec_public_key *identity_key; - - axolotl_buffer *serialized; -}; - struct ciphertext_message { - axolotl_type_base base; + signal_type_base base; int message_type; - axolotl_context *global_context; - axolotl_buffer *serialized; + signal_context *global_context; + signal_buffer *serialized; }; -struct whisper_message +struct signal_message { ciphertext_message base_message; uint8_t message_version; ec_public_key *sender_ratchet_key; uint32_t counter; uint32_t previous_counter; - axolotl_buffer *ciphertext; + signal_buffer *ciphertext; }; -struct pre_key_whisper_message +struct pre_key_signal_message { ciphertext_message base_message; uint8_t version; @@ -56,7 +38,7 @@ struct pre_key_whisper_message uint32_t signed_pre_key_id; ec_public_key *base_key; ec_public_key *identity_key; - whisper_message *message; + signal_message *message; }; struct sender_key_message @@ -65,7 +47,7 @@ struct sender_key_message uint8_t message_version; uint32_t key_id; uint32_t iteration; - axolotl_buffer *ciphertext; + signal_buffer *ciphertext; }; struct sender_key_distribution_message @@ -73,360 +55,23 @@ struct sender_key_distribution_message ciphertext_message base_message; uint32_t id; uint32_t iteration; - axolotl_buffer *chain_key; + signal_buffer *chain_key; ec_public_key *signature_key; }; -static int key_exchange_message_serialize(axolotl_buffer **buffer, const key_exchange_message *message); - -static int whisper_message_serialize(axolotl_buffer **buffer, const whisper_message *message); -static int whisper_message_get_mac(axolotl_buffer **buffer, +static int signal_message_serialize(signal_buffer **buffer, const signal_message *message); +static int signal_message_get_mac(signal_buffer **buffer, uint8_t message_version, ec_public_key *sender_identity_key, ec_public_key *receiver_identity_key, const uint8_t *mac_key, size_t mac_key_len, const uint8_t *serialized, size_t serialized_len, - axolotl_context *global_context); - -static int pre_key_whisper_message_serialize(axolotl_buffer **buffer, const pre_key_whisper_message *message); - -static int sender_key_message_serialize(axolotl_buffer **buffer, const sender_key_message *message, ec_private_key *signature_key, axolotl_context *global_context); -static int sender_key_distribution_message_serialize(axolotl_buffer **buffer, const sender_key_distribution_message *message); - -int key_exchange_message_create(key_exchange_message **message, - uint8_t message_version, uint32_t sequence, uint32_t flags, - ec_public_key *base_key, uint8_t *base_key_signature, - ec_public_key *ratchet_key, ec_public_key *identity_key) -{ - int result = 0; - key_exchange_message *result_message = 0; - - result_message = malloc(sizeof(key_exchange_message)); - if(!result_message) { - result = AX_ERR_NOMEM; - goto complete; - } - memset(result_message, 0, sizeof(key_exchange_message)); - AXOLOTL_INIT(result_message, key_exchange_message_destroy); - - result_message->supported_version = CIPHERTEXT_CURRENT_VERSION; - result_message->version = message_version; - result_message->sequence = sequence; - result_message->flags = flags; - - AXOLOTL_REF(base_key); - result_message->base_key = base_key; - - memcpy(result_message->base_key_signature, base_key_signature, sizeof(result_message->base_key_signature)); - - AXOLOTL_REF(ratchet_key); - result_message->ratchet_key = ratchet_key; - - AXOLOTL_REF(identity_key); - result_message->identity_key = identity_key; - - result = key_exchange_message_serialize(&result_message->serialized, result_message); - if(result < 0) { - goto complete; - } - result = 0; - -complete: - if(result >= 0) { - *message = result_message; - } - else { - if(result_message) { - AXOLOTL_UNREF(result_message); - } - } - return result; -} - -static int key_exchange_message_serialize(axolotl_buffer **buffer, const key_exchange_message *message) -{ - int result = 0; - size_t result_size = 0; - axolotl_buffer *result_buf = 0; - Textsecure__KeyExchangeMessage message_structure = TEXTSECURE__KEY_EXCHANGE_MESSAGE__INIT; - size_t len = 0; - uint8_t *data = 0; - - uint8_t version = (message->version << 4) | message->supported_version; - - message_structure.has_id = 1; - message_structure.id = (message->sequence << 5) | message->flags; - - if(message->base_key) { - message_structure.has_basekey = 1; - result = ec_public_key_serialize_protobuf(&message_structure.basekey, message->base_key); - if(result < 0) { - goto complete; - } - } - - if(message->ratchet_key) { - message_structure.has_ratchetkey = 1; - result = ec_public_key_serialize_protobuf(&message_structure.ratchetkey, message->ratchet_key); - if(result < 0) { - goto complete; - } - } - - if(message->identity_key) { - message_structure.has_identitykey = 1; - result = ec_public_key_serialize_protobuf(&message_structure.identitykey, message->identity_key); - if(result < 0) { - goto complete; - } - } - - if(message->version >= 3) { - message_structure.has_basekeysignature = 1; - message_structure.basekeysignature.len = sizeof(message->base_key_signature); - message_structure.basekeysignature.data = malloc(message_structure.basekeysignature.len); - if(!message_structure.basekeysignature.data) { - result = AX_ERR_NOMEM; - goto complete; - } - memcpy(message_structure.basekeysignature.data, message->base_key_signature, message_structure.basekeysignature.len); - } - - len = textsecure__key_exchange_message__get_packed_size(&message_structure); - - result_buf = axolotl_buffer_alloc(len + 1); - if(!result_buf) { - result = AX_ERR_NOMEM; - goto complete; - } - - data = axolotl_buffer_data(result_buf); - data[0] = version; - - result_size = textsecure__key_exchange_message__pack(&message_structure, data + 1); - if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; - result_buf = 0; - goto complete; - } - -complete: - if(message_structure.basekey.data) { - free(message_structure.basekey.data); - } - if(message_structure.ratchetkey.data) { - free(message_structure.ratchetkey.data); - } - if(message_structure.identitykey.data) { - free(message_structure.identitykey.data); - } - if(message_structure.basekeysignature.data) { - free(message_structure.basekeysignature.data); - } - if(result >= 0) { - *buffer = result_buf; - } - return result; -} - -int key_exchange_message_deserialize(key_exchange_message **message, const uint8_t *data, size_t len, axolotl_context *global_context) -{ - int result = 0; - key_exchange_message *result_message = 0; - Textsecure__KeyExchangeMessage *message_structure = 0; - uint8_t version = 0; - uint8_t supported_version = 0; - - if(!data || len <= 1) { - result = AX_ERR_INVAL; - goto complete; - } - - version = (data[0] & 0xF0) >> 4; - supported_version = data[0] & 0x0F; - - if(version <= CIPHERTEXT_UNSUPPORTED_VERSION) { - axolotl_log(global_context, AX_LOG_WARNING, "Unsupported legacy version: %d", version); - result = AX_ERR_LEGACY_MESSAGE; - goto complete; - } + signal_context *global_context); - if(version > CIPHERTEXT_CURRENT_VERSION) { - axolotl_log(global_context, AX_LOG_WARNING, "Unknown version: %d", version); - result = AX_ERR_INVALID_VERSION; - goto complete; - } +static int pre_key_signal_message_serialize(signal_buffer **buffer, const pre_key_signal_message *message); - message_structure = textsecure__key_exchange_message__unpack(0, len - 1, data + 1); - if(!message_structure) { - result = AX_ERR_INVALID_PROTO_BUF; - goto complete; - } - - if(!message_structure->has_id || !message_structure->has_basekey - || !message_structure->has_ratchetkey || !message_structure->has_identitykey - || (version >= 3 && !message_structure->has_basekeysignature)) { - axolotl_log(global_context, AX_LOG_WARNING, "Some required fields missing"); - result = AX_ERR_INVALID_MESSAGE; - goto complete; - } - - if(message_structure->has_basekeysignature && message_structure->basekeysignature.len != CURVE_SIGNATURE_LEN) { - axolotl_log(global_context, AX_LOG_WARNING, "Invalid base key signature length: %d", message_structure->basekeysignature.len); - result = AX_ERR_INVALID_MESSAGE; - goto complete; - } - - result_message = malloc(sizeof(key_exchange_message)); - if(!result_message) { - result = AX_ERR_NOMEM; - goto complete; - } - memset(result_message, 0, sizeof(key_exchange_message)); - AXOLOTL_INIT(result_message, key_exchange_message_destroy); - - result_message->version = version; - result_message->supported_version = supported_version; - result_message->sequence = message_structure->id >> 5; - result_message->flags = message_structure->id & 0x1F; - - result = curve_decode_point(&result_message->base_key, - message_structure->basekey.data, message_structure->basekey.len, global_context); - if(result < 0) { - goto complete; - } - - if(message_structure->has_basekeysignature) { - memcpy(result_message->base_key_signature, - message_structure->basekeysignature.data, - message_structure->basekeysignature.len); - } - - result = curve_decode_point(&result_message->ratchet_key, - message_structure->ratchetkey.data, message_structure->ratchetkey.len, global_context); - if(result < 0) { - goto complete; - } - - result = curve_decode_point(&result_message->identity_key, - message_structure->identitykey.data, message_structure->identitykey.len, global_context); - if(result < 0) { - goto complete; - } - - result_message->serialized = axolotl_buffer_alloc(len); - if(!result_message->serialized) { - result = AX_ERR_NOMEM; - goto complete; - } - memcpy(result_message->serialized, data, len); - -complete: - if(message_structure) { - textsecure__key_exchange_message__free_unpacked(message_structure, 0); - } - if(result >= 0) { - *message = result_message; - } - else { - if(result_message) { - AXOLOTL_UNREF(result_message); - } - } - return result; -} - -axolotl_buffer *key_exchange_message_get_serialized(const key_exchange_message *message) -{ - assert(message); - assert(message->serialized); - return message->serialized; -} - -uint8_t key_exchange_message_get_version(const key_exchange_message *message) -{ - assert(message); - return message->version; -} - -ec_public_key *key_exchange_message_get_base_key(const key_exchange_message *message) -{ - assert(message); - return message->base_key; -} - -uint8_t *key_exchange_message_get_base_key_signature(key_exchange_message *message) -{ - assert(message); - return message->base_key_signature; -} - -ec_public_key *key_exchange_message_get_ratchet_key(const key_exchange_message *message) -{ - assert(message); - return message->ratchet_key; -} - -ec_public_key *key_exchange_message_get_identity_key(const key_exchange_message *message) -{ - assert(message); - return message->identity_key; -} - -int key_exchange_message_has_identity_key(const key_exchange_message *message) -{ - assert(message); - return 1; -} - -uint8_t key_exchange_message_get_max_version(const key_exchange_message *message) -{ - assert(message); - return message->supported_version; -} - -int key_exchange_message_is_response(const key_exchange_message *message) -{ - assert(message); - return (message->flags & KEY_EXCHANGE_RESPONSE_FLAG) != 0; -} - -int key_exchange_message_is_initiate(const key_exchange_message *message) -{ - assert(message); - return (message->flags & KEY_EXCHANGE_INITIATE_FLAG) != 0; -} - -int key_exchange_message_is_response_for_simultaneous_initiate(const key_exchange_message *message) -{ - assert(message); - return (message->flags & KEY_EXCHANGE_SIMULTAENOUS_INITIATE_FLAG) != 0; -} - -uint32_t key_exchange_message_get_flags(const key_exchange_message *message) -{ - assert(message); - return message->flags; -} - -uint32_t key_exchange_message_get_sequence(const key_exchange_message *message) -{ - assert(message); - return message->sequence; -} - -void key_exchange_message_destroy(axolotl_type_base *type) -{ - key_exchange_message *message = (key_exchange_message *)type; - AXOLOTL_UNREF(message->base_key); - AXOLOTL_UNREF(message->ratchet_key); - AXOLOTL_UNREF(message->identity_key); - if(message->serialized) { - axolotl_buffer_free(message->serialized); - } - free(message); -} +static int sender_key_message_serialize(signal_buffer **buffer, const sender_key_message *message, ec_private_key *signature_key, signal_context *global_context); +static int sender_key_distribution_message_serialize(signal_buffer **buffer, const sender_key_distribution_message *message); /*------------------------------------------------------------------------*/ @@ -436,7 +81,7 @@ int ciphertext_message_get_type(const ciphertext_message *message) return message->message_type; } -axolotl_buffer *ciphertext_message_get_serialized(const ciphertext_message *message) +signal_buffer *ciphertext_message_get_serialized(const ciphertext_message *message) { assert(message); return message->serialized; @@ -444,76 +89,76 @@ axolotl_buffer *ciphertext_message_get_serialized(const ciphertext_message *mess /*------------------------------------------------------------------------*/ -int whisper_message_create(whisper_message **message, uint8_t message_version, +int signal_message_create(signal_message **message, uint8_t message_version, const uint8_t *mac_key, size_t mac_key_len, ec_public_key *sender_ratchet_key, uint32_t counter, uint32_t previous_counter, const uint8_t *ciphertext, size_t ciphertext_len, ec_public_key *sender_identity_key, ec_public_key *receiver_identity_key, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; - axolotl_buffer *message_buf = 0; - axolotl_buffer *mac_buf = 0; - whisper_message *result_message = 0; + signal_buffer *message_buf = 0; + signal_buffer *mac_buf = 0; + signal_message *result_message = 0; assert(global_context); - result_message = malloc(sizeof(whisper_message)); + result_message = malloc(sizeof(signal_message)); if(!result_message) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - memset(result_message, 0, sizeof(whisper_message)); - AXOLOTL_INIT(result_message, whisper_message_destroy); + memset(result_message, 0, sizeof(signal_message)); + SIGNAL_INIT(result_message, signal_message_destroy); - result_message->base_message.message_type = CIPHERTEXT_WHISPER_TYPE; + result_message->base_message.message_type = CIPHERTEXT_SIGNAL_TYPE; result_message->base_message.global_context = global_context; - AXOLOTL_REF(sender_ratchet_key); + SIGNAL_REF(sender_ratchet_key); result_message->sender_ratchet_key = sender_ratchet_key; result_message->counter = counter; result_message->previous_counter = previous_counter; - result_message->ciphertext = axolotl_buffer_create(ciphertext, ciphertext_len); + result_message->ciphertext = signal_buffer_create(ciphertext, ciphertext_len); if(!result_message->ciphertext) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } result_message->message_version = message_version; - result = whisper_message_serialize(&message_buf, result_message); + result = signal_message_serialize(&message_buf, result_message); if(result < 0) { goto complete; } - result = whisper_message_get_mac(&mac_buf, + result = signal_message_get_mac(&mac_buf, message_version, sender_identity_key, receiver_identity_key, mac_key, mac_key_len, - axolotl_buffer_data(message_buf), - axolotl_buffer_len(message_buf), + signal_buffer_data(message_buf), + signal_buffer_len(message_buf), global_context); if(result < 0) { goto complete; } - result_message->base_message.serialized = axolotl_buffer_append( + result_message->base_message.serialized = signal_buffer_append( message_buf, - axolotl_buffer_data(mac_buf), - axolotl_buffer_len(mac_buf)); + signal_buffer_data(mac_buf), + signal_buffer_len(mac_buf)); if(result_message->base_message.serialized) { message_buf = 0; } else { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; } complete: if(message_buf) { - axolotl_buffer_free(message_buf); + signal_buffer_free(message_buf); } if(mac_buf) { - axolotl_buffer_free(mac_buf); + signal_buffer_free(mac_buf); } if(result >= 0) { result = 0; @@ -521,18 +166,18 @@ complete: } else { if(result_message) { - AXOLOTL_UNREF(result_message); + SIGNAL_UNREF(result_message); } } return result; } -static int whisper_message_serialize(axolotl_buffer **buffer, const whisper_message *message) +static int signal_message_serialize(signal_buffer **buffer, const signal_message *message) { int result = 0; size_t result_size = 0; - axolotl_buffer *result_buf = 0; - Textsecure__WhisperMessage message_structure = TEXTSECURE__WHISPER_MESSAGE__INIT; + signal_buffer *result_buf = 0; + Textsecure__SignalMessage message_structure = TEXTSECURE__SIGNAL_MESSAGE__INIT; size_t len = 0; uint8_t *data = 0; @@ -550,25 +195,25 @@ static int whisper_message_serialize(axolotl_buffer **buffer, const whisper_mess message_structure.previouscounter = message->previous_counter; message_structure.has_previouscounter = 1; - message_structure.ciphertext.data = axolotl_buffer_data(message->ciphertext); - message_structure.ciphertext.len = axolotl_buffer_len(message->ciphertext); + message_structure.ciphertext.data = signal_buffer_data(message->ciphertext); + message_structure.ciphertext.len = signal_buffer_len(message->ciphertext); message_structure.has_ciphertext = 1; - len = textsecure__whisper_message__get_packed_size(&message_structure); + len = textsecure__signal_message__get_packed_size(&message_structure); - result_buf = axolotl_buffer_alloc(len + 1); + result_buf = signal_buffer_alloc(len + 1); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); data[0] = version; - result_size = textsecure__whisper_message__pack(&message_structure, data + 1); + result_size = textsecure__signal_message__pack(&message_structure, data + 1); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } @@ -583,11 +228,11 @@ complete: return result; } -int whisper_message_deserialize(whisper_message **message, const uint8_t *data, size_t len, axolotl_context *global_context) +int signal_message_deserialize(signal_message **message, const uint8_t *data, size_t len, signal_context *global_context) { int result = 0; - whisper_message *result_message = 0; - Textsecure__WhisperMessage *message_structure = 0; + signal_message *result_message = 0; + Textsecure__SignalMessage *message_structure = 0; uint8_t version = 0; uint8_t *ciphertext_data = 0; uint8_t *serialized_data = 0; @@ -596,8 +241,8 @@ int whisper_message_deserialize(whisper_message **message, const uint8_t *data, assert(global_context); - if(!data || len <= 1 + WHISPER_MESSAGE_MAC_LENGTH) { - result = AX_ERR_INVAL; + if(!data || len <= 1 + SIGNAL_MESSAGE_MAC_LENGTH) { + result = SG_ERR_INVAL; goto complete; } @@ -605,43 +250,43 @@ int whisper_message_deserialize(whisper_message **message, const uint8_t *data, /* Set some pointers and lengths for the sections of the raw data */ message_data = data + 1; - message_len = len - 1 - WHISPER_MESSAGE_MAC_LENGTH; + message_len = len - 1 - SIGNAL_MESSAGE_MAC_LENGTH; if(version <= CIPHERTEXT_UNSUPPORTED_VERSION) { - axolotl_log(global_context, AX_LOG_WARNING, "Unsupported legacy version: %d", version); - result = AX_ERR_LEGACY_MESSAGE; + signal_log(global_context, SG_LOG_WARNING, "Unsupported legacy version: %d", version); + result = SG_ERR_LEGACY_MESSAGE; goto complete; } if(version > CIPHERTEXT_CURRENT_VERSION) { - axolotl_log(global_context, AX_LOG_WARNING, "Unknown version: %d", version); - result = AX_ERR_INVALID_MESSAGE; + signal_log(global_context, SG_LOG_WARNING, "Unknown version: %d", version); + result = SG_ERR_INVALID_MESSAGE; goto complete; } - message_structure = textsecure__whisper_message__unpack(0, message_len, message_data); + message_structure = textsecure__signal_message__unpack(0, message_len, message_data); if(!message_structure) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } if(!message_structure->has_ciphertext || !message_structure->has_counter || !message_structure->has_ratchetkey) { - axolotl_log(global_context, AX_LOG_WARNING, "Incomplete message"); - result = AX_ERR_INVALID_MESSAGE; + signal_log(global_context, SG_LOG_WARNING, "Incomplete message"); + result = SG_ERR_INVALID_MESSAGE; goto complete; } - result_message = malloc(sizeof(whisper_message)); + result_message = malloc(sizeof(signal_message)); if(!result_message) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - memset(result_message, 0, sizeof(whisper_message)); - AXOLOTL_INIT(result_message, whisper_message_destroy); + memset(result_message, 0, sizeof(signal_message)); + SIGNAL_INIT(result_message, signal_message_destroy); - result_message->base_message.message_type = CIPHERTEXT_WHISPER_TYPE; + result_message->base_message.message_type = CIPHERTEXT_SIGNAL_TYPE; result_message->base_message.global_context = global_context; result = curve_decode_point(&result_message->sender_ratchet_key, @@ -654,49 +299,49 @@ int whisper_message_deserialize(whisper_message **message, const uint8_t *data, result_message->counter = message_structure->counter; result_message->previous_counter = message_structure->previouscounter; - result_message->ciphertext = axolotl_buffer_alloc(message_structure->ciphertext.len); + result_message->ciphertext = signal_buffer_alloc(message_structure->ciphertext.len); if(!result_message->ciphertext) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - ciphertext_data = axolotl_buffer_data(result_message->ciphertext); + ciphertext_data = signal_buffer_data(result_message->ciphertext); memcpy(ciphertext_data, message_structure->ciphertext.data, message_structure->ciphertext.len); - result_message->base_message.serialized = axolotl_buffer_alloc(len); + result_message->base_message.serialized = signal_buffer_alloc(len); if(!result_message->base_message.serialized) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - serialized_data = axolotl_buffer_data(result_message->base_message.serialized); + serialized_data = signal_buffer_data(result_message->base_message.serialized); memcpy(serialized_data, data, len); complete: if(message_structure) { - textsecure__whisper_message__free_unpacked(message_structure, 0); + textsecure__signal_message__free_unpacked(message_structure, 0); } if(result >= 0) { *message = result_message; } else { if(result_message) { - AXOLOTL_UNREF(result_message); + SIGNAL_UNREF(result_message); } } return result; } -int whisper_message_copy(whisper_message **message, whisper_message *other_message, axolotl_context *global_context) +int signal_message_copy(signal_message **message, signal_message *other_message, signal_context *global_context) { int result = 0; - whisper_message *result_message = 0; + signal_message *result_message = 0; assert(other_message); assert(global_context); - result = whisper_message_deserialize( + result = signal_message_deserialize( &result_message, - axolotl_buffer_data(other_message->base_message.serialized), - axolotl_buffer_len(other_message->base_message.serialized), + signal_buffer_data(other_message->base_message.serialized), + signal_buffer_len(other_message->base_message.serialized), global_context); if(result >= 0) { *message = result_message; @@ -705,45 +350,45 @@ int whisper_message_copy(whisper_message **message, whisper_message *other_messa return result; } -ec_public_key *whisper_message_get_sender_ratchet_key(const whisper_message *message) +ec_public_key *signal_message_get_sender_ratchet_key(const signal_message *message) { assert(message); return message->sender_ratchet_key; } -uint8_t whisper_message_get_message_version(const whisper_message *message) +uint8_t signal_message_get_message_version(const signal_message *message) { assert(message); return message->message_version; } -uint32_t whisper_message_get_counter(const whisper_message *message) +uint32_t signal_message_get_counter(const signal_message *message) { assert(message); return message->counter; } -axolotl_buffer *whisper_message_get_body(const whisper_message *message) +signal_buffer *signal_message_get_body(const signal_message *message) { assert(message); return message->ciphertext; } -int whisper_message_verify_mac(whisper_message *message, +int signal_message_verify_mac(signal_message *message, uint8_t message_version, ec_public_key *sender_identity_key, ec_public_key *receiver_identity_key, const uint8_t *mac_key, size_t mac_key_len, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; - axolotl_buffer *our_mac_buffer = 0; + signal_buffer *our_mac_buffer = 0; uint8_t *serialized_data = 0; size_t serialized_len = 0; uint8_t *serialized_message_data = 0; size_t serialized_message_len = 0; uint8_t *their_mac_data = 0; - const size_t their_mac_len = WHISPER_MESSAGE_MAC_LENGTH; + const size_t their_mac_len = SIGNAL_MESSAGE_MAC_LENGTH; uint8_t *our_mac_data = 0; size_t our_mac_len = 0; @@ -751,13 +396,13 @@ int whisper_message_verify_mac(whisper_message *message, assert(message->base_message.serialized); /* Set some pointers and lengths for the sections of the raw data */ - serialized_data = axolotl_buffer_data(message->base_message.serialized); - serialized_len = axolotl_buffer_len(message->base_message.serialized); + serialized_data = signal_buffer_data(message->base_message.serialized); + serialized_len = signal_buffer_len(message->base_message.serialized); serialized_message_data = serialized_data; - serialized_message_len = serialized_len - WHISPER_MESSAGE_MAC_LENGTH; + serialized_message_len = serialized_len - SIGNAL_MESSAGE_MAC_LENGTH; their_mac_data = serialized_data + serialized_message_len; - result = whisper_message_get_mac(&our_mac_buffer, + result = signal_message_get_mac(&our_mac_buffer, message->message_version, sender_identity_key, receiver_identity_key, mac_key, mac_key_len, @@ -767,48 +412,48 @@ int whisper_message_verify_mac(whisper_message *message, goto complete; } - our_mac_data = axolotl_buffer_data(our_mac_buffer); - our_mac_len = axolotl_buffer_len(our_mac_buffer); + our_mac_data = signal_buffer_data(our_mac_buffer); + our_mac_len = signal_buffer_len(our_mac_buffer); if(our_mac_len != their_mac_len) { - axolotl_log(global_context, AX_LOG_WARNING, "MAC length mismatch: %d != %d", our_mac_len, their_mac_len); - result = AX_ERR_UNKNOWN; + signal_log(global_context, SG_LOG_WARNING, "MAC length mismatch: %d != %d", our_mac_len, their_mac_len); + result = SG_ERR_UNKNOWN; goto complete; } - if(axolotl_constant_memcmp(our_mac_data, their_mac_data, our_mac_len) == 0) { + if(signal_constant_memcmp(our_mac_data, their_mac_data, our_mac_len) == 0) { result = 1; } else { - axolotl_log(global_context, AX_LOG_NOTICE, "Bad MAC"); + signal_log(global_context, SG_LOG_NOTICE, "Bad MAC"); result = 0; } complete: if(our_mac_buffer) { - axolotl_buffer_free(our_mac_buffer); + signal_buffer_free(our_mac_buffer); } return result; } -static int whisper_message_get_mac(axolotl_buffer **buffer, +static int signal_message_get_mac(signal_buffer **buffer, uint8_t message_version, ec_public_key *sender_identity_key, ec_public_key *receiver_identity_key, const uint8_t *mac_key, size_t mac_key_len, const uint8_t *serialized, size_t serialized_len, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; void *hmac_context; - axolotl_buffer *sender_key_buffer = 0; - axolotl_buffer *receiver_key_buffer = 0; - axolotl_buffer *full_mac_buffer = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *sender_key_buffer = 0; + signal_buffer *receiver_key_buffer = 0; + signal_buffer *full_mac_buffer = 0; + signal_buffer *result_buf = 0; uint8_t *result_data = 0; assert(global_context); - result = axolotl_hmac_sha256_init(global_context, + result = signal_hmac_sha256_init(global_context, &hmac_context, mac_key, mac_key_len); if(result < 0) { goto complete; @@ -820,9 +465,9 @@ static int whisper_message_get_mac(axolotl_buffer **buffer, goto complete; } - result = axolotl_hmac_sha256_update(global_context, hmac_context, - axolotl_buffer_data(sender_key_buffer), - axolotl_buffer_len(sender_key_buffer)); + result = signal_hmac_sha256_update(global_context, hmac_context, + signal_buffer_data(sender_key_buffer), + signal_buffer_len(sender_key_buffer)); if(result < 0) { goto complete; } @@ -832,86 +477,86 @@ static int whisper_message_get_mac(axolotl_buffer **buffer, goto complete; } - result = axolotl_hmac_sha256_update(global_context, hmac_context, - axolotl_buffer_data(receiver_key_buffer), - axolotl_buffer_len(receiver_key_buffer)); + result = signal_hmac_sha256_update(global_context, hmac_context, + signal_buffer_data(receiver_key_buffer), + signal_buffer_len(receiver_key_buffer)); if(result < 0) { goto complete; } } - result = axolotl_hmac_sha256_update(global_context, hmac_context, + result = signal_hmac_sha256_update(global_context, hmac_context, serialized, serialized_len); if(result < 0) { goto complete; } - result = axolotl_hmac_sha256_final(global_context, + result = signal_hmac_sha256_final(global_context, hmac_context, &full_mac_buffer); - if(result < 0 || axolotl_buffer_len(full_mac_buffer) < WHISPER_MESSAGE_MAC_LENGTH) { - if(result >= 0) { result = AX_ERR_UNKNOWN; } + if(result < 0 || signal_buffer_len(full_mac_buffer) < SIGNAL_MESSAGE_MAC_LENGTH) { + if(result >= 0) { result = SG_ERR_UNKNOWN; } goto complete; } - result_buf = axolotl_buffer_alloc(WHISPER_MESSAGE_MAC_LENGTH); + result_buf = signal_buffer_alloc(SIGNAL_MESSAGE_MAC_LENGTH); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - result_data = axolotl_buffer_data(result_buf); - memcpy(result_data, axolotl_buffer_data(full_mac_buffer), WHISPER_MESSAGE_MAC_LENGTH); + result_data = signal_buffer_data(result_buf); + memcpy(result_data, signal_buffer_data(full_mac_buffer), SIGNAL_MESSAGE_MAC_LENGTH); complete: - axolotl_hmac_sha256_cleanup(global_context, hmac_context); - axolotl_buffer_free(sender_key_buffer); - axolotl_buffer_free(receiver_key_buffer); - axolotl_buffer_free(full_mac_buffer); + signal_hmac_sha256_cleanup(global_context, hmac_context); + signal_buffer_free(sender_key_buffer); + signal_buffer_free(receiver_key_buffer); + signal_buffer_free(full_mac_buffer); if(result >= 0) { *buffer = result_buf; } return result; } -int whisper_message_is_legacy(const uint8_t *data, size_t len) +int signal_message_is_legacy(const uint8_t *data, size_t len) { return data && len >= 1 && ((data[0] & 0xF0) >> 4) <= CIPHERTEXT_UNSUPPORTED_VERSION; } -void whisper_message_destroy(axolotl_type_base *type) +void signal_message_destroy(signal_type_base *type) { - whisper_message *message = (whisper_message *)type; + signal_message *message = (signal_message *)type; if(message->base_message.serialized) { - axolotl_buffer_free(message->base_message.serialized); + signal_buffer_free(message->base_message.serialized); } - AXOLOTL_UNREF(message->sender_ratchet_key); + SIGNAL_UNREF(message->sender_ratchet_key); if(message->ciphertext) { - axolotl_buffer_free(message->ciphertext); + signal_buffer_free(message->ciphertext); } free(message); } /*------------------------------------------------------------------------*/ -int pre_key_whisper_message_create(pre_key_whisper_message **pre_key_message, +int pre_key_signal_message_create(pre_key_signal_message **pre_key_message, uint8_t message_version, uint32_t registration_id, const uint32_t *pre_key_id, uint32_t signed_pre_key_id, ec_public_key *base_key, ec_public_key *identity_key, - whisper_message *message, - axolotl_context *global_context) + signal_message *message, + signal_context *global_context) { int result = 0; - pre_key_whisper_message *result_message = 0; + pre_key_signal_message *result_message = 0; assert(global_context); - result_message = malloc(sizeof(pre_key_whisper_message)); + result_message = malloc(sizeof(pre_key_signal_message)); if(!result_message) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - memset(result_message, 0, sizeof(pre_key_whisper_message)); - AXOLOTL_INIT(result_message, pre_key_whisper_message_destroy); + memset(result_message, 0, sizeof(pre_key_signal_message)); + SIGNAL_INIT(result_message, pre_key_signal_message_destroy); result_message->base_message.message_type = CIPHERTEXT_PREKEY_TYPE; result_message->base_message.global_context = global_context; @@ -924,16 +569,16 @@ int pre_key_whisper_message_create(pre_key_whisper_message **pre_key_message, } result_message->signed_pre_key_id = signed_pre_key_id; - AXOLOTL_REF(base_key); + SIGNAL_REF(base_key); result_message->base_key = base_key; - AXOLOTL_REF(identity_key); + SIGNAL_REF(identity_key); result_message->identity_key = identity_key; - AXOLOTL_REF(message); + SIGNAL_REF(message); result_message->message = message; - result = pre_key_whisper_message_serialize(&result_message->base_message.serialized, result_message); + result = pre_key_signal_message_serialize(&result_message->base_message.serialized, result_message); if(result >= 0) { result = 0; @@ -941,19 +586,19 @@ int pre_key_whisper_message_create(pre_key_whisper_message **pre_key_message, } else { if(result_message) { - AXOLOTL_UNREF(result_message); + SIGNAL_UNREF(result_message); } } return result; } -static int pre_key_whisper_message_serialize(axolotl_buffer **buffer, const pre_key_whisper_message *message) +static int pre_key_signal_message_serialize(signal_buffer **buffer, const pre_key_signal_message *message) { int result = 0; size_t result_size = 0; - axolotl_buffer *result_buf = 0; - Textsecure__PreKeyWhisperMessage message_structure = TEXTSECURE__PRE_KEY_WHISPER_MESSAGE__INIT; - axolotl_buffer *inner_message_buffer = 0; + signal_buffer *result_buf = 0; + Textsecure__PreKeySignalMessage message_structure = TEXTSECURE__PRE_KEY_SIGNAL_MESSAGE__INIT; + signal_buffer *inner_message_buffer = 0; size_t len = 0; uint8_t *data = 0; @@ -983,25 +628,25 @@ static int pre_key_whisper_message_serialize(axolotl_buffer **buffer, const pre_ message_structure.has_identitykey = 1; inner_message_buffer = message->message->base_message.serialized; - message_structure.message.data = axolotl_buffer_data(inner_message_buffer); - message_structure.message.len = axolotl_buffer_len(inner_message_buffer); + message_structure.message.data = signal_buffer_data(inner_message_buffer); + message_structure.message.len = signal_buffer_len(inner_message_buffer); message_structure.has_message = 1; - len = textsecure__pre_key_whisper_message__get_packed_size(&message_structure); + len = textsecure__pre_key_signal_message__get_packed_size(&message_structure); - result_buf = axolotl_buffer_alloc(len + 1); + result_buf = signal_buffer_alloc(len + 1); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); data[0] = version; - result_size = textsecure__pre_key_whisper_message__pack(&message_structure, data + 1); + result_size = textsecure__pre_key_signal_message__pack(&message_structure, data + 1); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } @@ -1019,13 +664,13 @@ complete: return result; } -int pre_key_whisper_message_deserialize(pre_key_whisper_message **message, +int pre_key_signal_message_deserialize(pre_key_signal_message **message, const uint8_t *data, size_t len, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; - pre_key_whisper_message *result_message = 0; - Textsecure__PreKeyWhisperMessage *message_structure = 0; + pre_key_signal_message *result_message = 0; + Textsecure__PreKeySignalMessage *message_structure = 0; uint8_t version = 0; const uint8_t *message_data = 0; size_t message_len = 0; @@ -1034,7 +679,7 @@ int pre_key_whisper_message_deserialize(pre_key_whisper_message **message, assert(global_context); if(!data || len <= 1) { - result = AX_ERR_INVAL; + result = SG_ERR_INVAL; goto complete; } @@ -1044,41 +689,40 @@ int pre_key_whisper_message_deserialize(pre_key_whisper_message **message, message_data = data + 1; message_len = len - 1; - if(version <= CIPHERTEXT_UNSUPPORTED_VERSION) { - axolotl_log(global_context, AX_LOG_WARNING, "Unsupported legacy version: %d", version); - result = AX_ERR_LEGACY_MESSAGE; + if(version < CIPHERTEXT_CURRENT_VERSION) { + signal_log(global_context, SG_LOG_WARNING, "Unsupported legacy version: %d", version); + result = SG_ERR_LEGACY_MESSAGE; goto complete; } if(version > CIPHERTEXT_CURRENT_VERSION) { - axolotl_log(global_context, AX_LOG_WARNING, "Unknown version: %d", version); - result = AX_ERR_INVALID_VERSION; + signal_log(global_context, SG_LOG_WARNING, "Unknown version: %d", version); + result = SG_ERR_INVALID_VERSION; goto complete; } - message_structure = textsecure__pre_key_whisper_message__unpack(0, message_len, message_data); + message_structure = textsecure__pre_key_signal_message__unpack(0, message_len, message_data); if(!message_structure) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } - if((version == 2 && !message_structure->has_prekeyid) || - (version == 3 && !message_structure->has_signedprekeyid) || + if(!message_structure->has_signedprekeyid || !message_structure->has_basekey || !message_structure->has_identitykey || !message_structure->has_message) { - axolotl_log(global_context, AX_LOG_WARNING, "Incomplete message"); - result = AX_ERR_INVALID_MESSAGE; + signal_log(global_context, SG_LOG_WARNING, "Incomplete message"); + result = SG_ERR_INVALID_MESSAGE; goto complete; } - result_message = malloc(sizeof(pre_key_whisper_message)); + result_message = malloc(sizeof(pre_key_signal_message)); if(!result_message) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - memset(result_message, 0, sizeof(pre_key_whisper_message)); - AXOLOTL_INIT(result_message, pre_key_whisper_message_destroy); + memset(result_message, 0, sizeof(pre_key_signal_message)); + SIGNAL_INIT(result_message, pre_key_signal_message_destroy); result_message->base_message.message_type = CIPHERTEXT_PREKEY_TYPE; result_message->base_message.global_context = global_context; @@ -1115,7 +759,7 @@ int pre_key_whisper_message_deserialize(pre_key_whisper_message **message, } if(message_structure->has_message) { - result = whisper_message_deserialize(&result_message->message, + result = signal_message_deserialize(&result_message->message, message_structure->message.data, message_structure->message.len, global_context); @@ -1123,48 +767,48 @@ int pre_key_whisper_message_deserialize(pre_key_whisper_message **message, goto complete; } if(result_message->message->message_version != version) { - axolotl_log(global_context, AX_LOG_WARNING, "Inner message version mismatch: %d != %d", + signal_log(global_context, SG_LOG_WARNING, "Inner message version mismatch: %d != %d", result_message->message->message_version, version); - result = AX_ERR_INVALID_VERSION; + result = SG_ERR_INVALID_VERSION; goto complete; } } - result_message->base_message.serialized = axolotl_buffer_alloc(len); + result_message->base_message.serialized = signal_buffer_alloc(len); if(!result_message->base_message.serialized) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - serialized_data = axolotl_buffer_data(result_message->base_message.serialized); + serialized_data = signal_buffer_data(result_message->base_message.serialized); memcpy(serialized_data, data, len); complete: if(message_structure) { - textsecure__pre_key_whisper_message__free_unpacked(message_structure, 0); + textsecure__pre_key_signal_message__free_unpacked(message_structure, 0); } if(result >= 0) { *message = result_message; } else { if(result_message) { - AXOLOTL_UNREF(result_message); + SIGNAL_UNREF(result_message); } } return result; } -int pre_key_whisper_message_copy(pre_key_whisper_message **message, pre_key_whisper_message *other_message, axolotl_context *global_context) +int pre_key_signal_message_copy(pre_key_signal_message **message, pre_key_signal_message *other_message, signal_context *global_context) { int result = 0; - pre_key_whisper_message *result_message = 0; + pre_key_signal_message *result_message = 0; assert(other_message); assert(global_context); - result = pre_key_whisper_message_deserialize( + result = pre_key_signal_message_deserialize( &result_message, - axolotl_buffer_data(other_message->base_message.serialized), - axolotl_buffer_len(other_message->base_message.serialized), + signal_buffer_data(other_message->base_message.serialized), + signal_buffer_len(other_message->base_message.serialized), global_context); if(result >= 0) { *message = result_message; @@ -1173,65 +817,65 @@ int pre_key_whisper_message_copy(pre_key_whisper_message **message, pre_key_whis return result; } -uint8_t pre_key_whisper_message_get_message_version(const pre_key_whisper_message *message) +uint8_t pre_key_signal_message_get_message_version(const pre_key_signal_message *message) { assert(message); return message->version; } -ec_public_key *pre_key_whisper_message_get_identity_key(const pre_key_whisper_message *message) +ec_public_key *pre_key_signal_message_get_identity_key(const pre_key_signal_message *message) { assert(message); return message->identity_key; } -uint32_t pre_key_whisper_message_get_registration_id(const pre_key_whisper_message *message) +uint32_t pre_key_signal_message_get_registration_id(const pre_key_signal_message *message) { assert(message); return message->registration_id; } -int pre_key_whisper_message_has_pre_key_id(const pre_key_whisper_message *message) +int pre_key_signal_message_has_pre_key_id(const pre_key_signal_message *message) { assert(message); return message->has_pre_key_id; } -uint32_t pre_key_whisper_message_get_pre_key_id(const pre_key_whisper_message *message) +uint32_t pre_key_signal_message_get_pre_key_id(const pre_key_signal_message *message) { assert(message); assert(message->has_pre_key_id); return message->pre_key_id; } -uint32_t pre_key_whisper_message_get_signed_pre_key_id(const pre_key_whisper_message *message) +uint32_t pre_key_signal_message_get_signed_pre_key_id(const pre_key_signal_message *message) { assert(message); return message->signed_pre_key_id; } -ec_public_key *pre_key_whisper_message_get_base_key(const pre_key_whisper_message *message) +ec_public_key *pre_key_signal_message_get_base_key(const pre_key_signal_message *message) { assert(message); return message->base_key; } -whisper_message *pre_key_whisper_message_get_whisper_message(const pre_key_whisper_message *message) +signal_message *pre_key_signal_message_get_signal_message(const pre_key_signal_message *message) { assert(message); return message->message; } -void pre_key_whisper_message_destroy(axolotl_type_base *type) +void pre_key_signal_message_destroy(signal_type_base *type) { - pre_key_whisper_message *message = (pre_key_whisper_message *)type; + pre_key_signal_message *message = (pre_key_signal_message *)type; if(message->base_message.serialized) { - axolotl_buffer_free(message->base_message.serialized); + signal_buffer_free(message->base_message.serialized); } - AXOLOTL_UNREF(message->base_key); - AXOLOTL_UNREF(message->identity_key); - AXOLOTL_UNREF(message->message); + SIGNAL_UNREF(message->base_key); + SIGNAL_UNREF(message->identity_key); + SIGNAL_UNREF(message->message); free(message); } @@ -1239,21 +883,21 @@ int sender_key_message_create(sender_key_message **message, uint32_t key_id, uint32_t iteration, const uint8_t *ciphertext, size_t ciphertext_len, ec_private_key *signature_key, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; sender_key_message *result_message = 0; - axolotl_buffer *message_buf = 0; + signal_buffer *message_buf = 0; assert(global_context); result_message = malloc(sizeof(sender_key_message)); if(!result_message) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result_message, 0, sizeof(sender_key_message)); - AXOLOTL_INIT(result_message, sender_key_message_destroy); + SIGNAL_INIT(result_message, sender_key_message_destroy); result_message->base_message.message_type = CIPHERTEXT_SENDERKEY_TYPE; result_message->base_message.global_context = global_context; @@ -1262,9 +906,9 @@ int sender_key_message_create(sender_key_message **message, result_message->key_id = key_id; result_message->iteration = iteration; - result_message->ciphertext = axolotl_buffer_create(ciphertext, ciphertext_len); + result_message->ciphertext = signal_buffer_create(ciphertext, ciphertext_len); if(!result_message->ciphertext) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -1282,19 +926,19 @@ complete: } else { if(result_message) { - AXOLOTL_UNREF(result_message); + SIGNAL_UNREF(result_message); } } return result; } -int sender_key_message_serialize(axolotl_buffer **buffer, const sender_key_message *message, ec_private_key *signature_key, axolotl_context *global_context) +int sender_key_message_serialize(signal_buffer **buffer, const sender_key_message *message, ec_private_key *signature_key, signal_context *global_context) { int result = 0; uint8_t version = (CIPHERTEXT_CURRENT_VERSION << 4) | CIPHERTEXT_CURRENT_VERSION; size_t result_size = 0; - axolotl_buffer *result_buf = 0; - axolotl_buffer *signature_buf = 0; + signal_buffer *result_buf = 0; + signal_buffer *signature_buf = 0; Textsecure__SenderKeyMessage message_structure = TEXTSECURE__SENDER_KEY_MESSAGE__INIT; size_t len = 0; uint8_t *data = 0; @@ -1305,25 +949,25 @@ int sender_key_message_serialize(axolotl_buffer **buffer, const sender_key_messa message_structure.iteration = message->iteration; message_structure.has_iteration = 1; - message_structure.ciphertext.data = axolotl_buffer_data(message->ciphertext); - message_structure.ciphertext.len = axolotl_buffer_len(message->ciphertext); + message_structure.ciphertext.data = signal_buffer_data(message->ciphertext); + message_structure.ciphertext.len = signal_buffer_len(message->ciphertext); message_structure.has_ciphertext = 1; len = textsecure__sender_key_message__get_packed_size(&message_structure); - result_buf = axolotl_buffer_alloc(sizeof(version) + len + SIGNATURE_LENGTH); + result_buf = signal_buffer_alloc(sizeof(version) + len + SIGNATURE_LENGTH); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); data[0] = version; result_size = textsecure__sender_key_message__pack(&message_structure, data + sizeof(version)); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } @@ -1331,32 +975,32 @@ int sender_key_message_serialize(axolotl_buffer **buffer, const sender_key_messa result = curve_calculate_signature(global_context, &signature_buf, signature_key, data, len + sizeof(version)); if(result < 0) { - if(result == AX_ERR_INVALID_KEY) { - result = AX_ERR_UNKNOWN; + if(result == SG_ERR_INVALID_KEY) { + result = SG_ERR_UNKNOWN; } goto complete; } - else if(axolotl_buffer_len(signature_buf) != SIGNATURE_LENGTH) { - result = AX_ERR_UNKNOWN; + else if(signal_buffer_len(signature_buf) != SIGNATURE_LENGTH) { + result = SG_ERR_UNKNOWN; goto complete; } - memcpy(data + sizeof(version) + len, axolotl_buffer_data(signature_buf), SIGNATURE_LENGTH); + memcpy(data + sizeof(version) + len, signal_buffer_data(signature_buf), SIGNATURE_LENGTH); complete: - axolotl_buffer_free(signature_buf); + signal_buffer_free(signature_buf); if(result >= 0) { *buffer = result_buf; } else { - axolotl_buffer_free(result_buf); + signal_buffer_free(result_buf); } return result; } int sender_key_message_deserialize(sender_key_message **message, const uint8_t *data, size_t len, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; sender_key_message *result_message = 0; @@ -1368,7 +1012,7 @@ int sender_key_message_deserialize(sender_key_message **message, assert(global_context); if(!data || len <= sizeof(uint8_t) + SIGNATURE_LENGTH) { - result = AX_ERR_INVAL; + result = SG_ERR_INVAL; goto complete; } @@ -1377,38 +1021,38 @@ int sender_key_message_deserialize(sender_key_message **message, message_len = len - sizeof(uint8_t) - SIGNATURE_LENGTH; if(version < CIPHERTEXT_CURRENT_VERSION) { - axolotl_log(global_context, AX_LOG_WARNING, "Legacy message: %d", version); - result = AX_ERR_LEGACY_MESSAGE; + signal_log(global_context, SG_LOG_WARNING, "Legacy message: %d", version); + result = SG_ERR_LEGACY_MESSAGE; goto complete; } if(version > CIPHERTEXT_CURRENT_VERSION) { - axolotl_log(global_context, AX_LOG_WARNING, "Unknown version: %d", version); - result = AX_ERR_INVALID_VERSION; + signal_log(global_context, SG_LOG_WARNING, "Unknown version: %d", version); + result = SG_ERR_INVALID_VERSION; goto complete; } message_structure = textsecure__sender_key_message__unpack(0, message_len, message_data); if(!message_structure) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } if(!message_structure->has_id || !message_structure->has_iteration || !message_structure->has_ciphertext) { - axolotl_log(global_context, AX_LOG_WARNING, "Incomplete message"); - result = AX_ERR_INVALID_MESSAGE; + signal_log(global_context, SG_LOG_WARNING, "Incomplete message"); + result = SG_ERR_INVALID_MESSAGE; goto complete; } result_message = malloc(sizeof(sender_key_message)); if(!result_message) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } memset(result_message, 0, sizeof(sender_key_message)); - AXOLOTL_INIT(result_message, sender_key_message_destroy); + SIGNAL_INIT(result_message, sender_key_message_destroy); result_message->base_message.message_type = CIPHERTEXT_SENDERKEY_TYPE; result_message->base_message.global_context = global_context; @@ -1417,17 +1061,17 @@ int sender_key_message_deserialize(sender_key_message **message, result_message->iteration = message_structure->iteration; result_message->message_version = version; - result_message->ciphertext = axolotl_buffer_create( + result_message->ciphertext = signal_buffer_create( message_structure->ciphertext.data, message_structure->ciphertext.len); if(!result_message->ciphertext) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - result_message->base_message.serialized = axolotl_buffer_create(data, len); + result_message->base_message.serialized = signal_buffer_create(data, len); if(!result_message->base_message.serialized) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -1440,13 +1084,13 @@ complete: } else { if(result_message) { - AXOLOTL_UNREF(result_message); + SIGNAL_UNREF(result_message); } } return result; } -int sender_key_message_copy(sender_key_message **message, sender_key_message *other_message, axolotl_context *global_context) +int sender_key_message_copy(sender_key_message **message, sender_key_message *other_message, signal_context *global_context) { int result = 0; sender_key_message *result_message = 0; @@ -1456,8 +1100,8 @@ int sender_key_message_copy(sender_key_message **message, sender_key_message *ot result = sender_key_message_deserialize( &result_message, - axolotl_buffer_data(other_message->base_message.serialized), - axolotl_buffer_len(other_message->base_message.serialized), + signal_buffer_data(other_message->base_message.serialized), + signal_buffer_len(other_message->base_message.serialized), global_context); if(result >= 0) { *message = result_message; @@ -1478,7 +1122,7 @@ uint32_t sender_key_message_get_iteration(sender_key_message *message) return message->iteration; } -axolotl_buffer *sender_key_message_get_ciphertext(sender_key_message *message) +signal_buffer *sender_key_message_get_ciphertext(sender_key_message *message) { assert(message); return message->ciphertext; @@ -1492,17 +1136,17 @@ int sender_key_message_verify_signature(sender_key_message *message, ec_public_k assert(message); - data = axolotl_buffer_data(message->base_message.serialized); - data_len = axolotl_buffer_len(message->base_message.serialized) - SIGNATURE_LENGTH; + data = signal_buffer_data(message->base_message.serialized); + data_len = signal_buffer_len(message->base_message.serialized) - SIGNATURE_LENGTH; result = curve_verify_signature(signature_key, data, data_len, data + data_len, SIGNATURE_LENGTH); if(result == 0) { - axolotl_log(message->base_message.global_context, AX_LOG_ERROR, "Invalid signature!"); - result = AX_ERR_INVALID_MESSAGE; + signal_log(message->base_message.global_context, SG_LOG_ERROR, "Invalid signature!"); + result = SG_ERR_INVALID_MESSAGE; } else if(result < 0) { - result = AX_ERR_INVALID_MESSAGE; + result = SG_ERR_INVALID_MESSAGE; } else { result = 0; @@ -1511,15 +1155,15 @@ int sender_key_message_verify_signature(sender_key_message *message, ec_public_k return result; } -void sender_key_message_destroy(axolotl_type_base *type) +void sender_key_message_destroy(signal_type_base *type) { sender_key_message *message = (sender_key_message *)type; if(message->base_message.serialized) { - axolotl_buffer_free(message->base_message.serialized); + signal_buffer_free(message->base_message.serialized); } if(message->ciphertext) { - axolotl_buffer_free(message->ciphertext); + signal_buffer_free(message->ciphertext); } free(message); } @@ -1528,22 +1172,22 @@ int sender_key_distribution_message_create(sender_key_distribution_message **mes uint32_t id, uint32_t iteration, const uint8_t *chain_key, size_t chain_key_len, ec_public_key *signature_key, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; sender_key_distribution_message *result_message = 0; - axolotl_buffer *message_buf = 0; + signal_buffer *message_buf = 0; assert(global_context); result_message = malloc(sizeof(sender_key_distribution_message)); if(!result_message) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result_message, 0, sizeof(sender_key_distribution_message)); - AXOLOTL_INIT(result_message, sender_key_distribution_message_destroy); + SIGNAL_INIT(result_message, sender_key_distribution_message_destroy); result_message->base_message.message_type = CIPHERTEXT_SENDERKEY_DISTRIBUTION_TYPE; result_message->base_message.global_context = global_context; @@ -1551,12 +1195,12 @@ int sender_key_distribution_message_create(sender_key_distribution_message **mes result_message->id = id; result_message->iteration = iteration; - result_message->chain_key = axolotl_buffer_create(chain_key, chain_key_len); + result_message->chain_key = signal_buffer_create(chain_key, chain_key_len); if(!result_message->chain_key) { goto complete; } - AXOLOTL_REF(signature_key); + SIGNAL_REF(signature_key); result_message->signature_key = signature_key; result = sender_key_distribution_message_serialize(&message_buf, result_message); @@ -1573,18 +1217,18 @@ complete: } else { if(result_message) { - AXOLOTL_UNREF(result_message); + SIGNAL_UNREF(result_message); } } return result; } -int sender_key_distribution_message_serialize(axolotl_buffer **buffer, const sender_key_distribution_message *message) +int sender_key_distribution_message_serialize(signal_buffer **buffer, const sender_key_distribution_message *message) { int result = 0; uint8_t version = (CIPHERTEXT_CURRENT_VERSION << 4) | CIPHERTEXT_CURRENT_VERSION; size_t result_size = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; Textsecure__SenderKeyDistributionMessage message_structure = TEXTSECURE__SENDER_KEY_DISTRIBUTION_MESSAGE__INIT; size_t len = 0; uint8_t *data = 0; @@ -1595,8 +1239,8 @@ int sender_key_distribution_message_serialize(axolotl_buffer **buffer, const sen message_structure.iteration = message->iteration; message_structure.has_iteration = 1; - message_structure.chainkey.data = axolotl_buffer_data(message->chain_key); - message_structure.chainkey.len = axolotl_buffer_len(message->chain_key); + message_structure.chainkey.data = signal_buffer_data(message->chain_key); + message_structure.chainkey.len = signal_buffer_len(message->chain_key); message_structure.has_chainkey = 1; result = ec_public_key_serialize_protobuf(&message_structure.signingkey, message->signature_key); @@ -1607,19 +1251,19 @@ int sender_key_distribution_message_serialize(axolotl_buffer **buffer, const sen len = textsecure__sender_key_distribution_message__get_packed_size(&message_structure); - result_buf = axolotl_buffer_alloc(sizeof(version) + len); + result_buf = signal_buffer_alloc(sizeof(version) + len); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); data[0] = version; result_size = textsecure__sender_key_distribution_message__pack(&message_structure, data + sizeof(version)); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } @@ -1632,14 +1276,14 @@ complete: *buffer = result_buf; } else { - axolotl_buffer_free(result_buf); + signal_buffer_free(result_buf); } return result; } int sender_key_distribution_message_deserialize(sender_key_distribution_message **message, const uint8_t *data, size_t len, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; sender_key_distribution_message *result_message = 0; @@ -1651,7 +1295,7 @@ int sender_key_distribution_message_deserialize(sender_key_distribution_message assert(global_context); if(!data || len <= sizeof(uint8_t)) { - result = AX_ERR_INVAL; + result = SG_ERR_INVAL; goto complete; } @@ -1660,20 +1304,20 @@ int sender_key_distribution_message_deserialize(sender_key_distribution_message message_len = len - sizeof(uint8_t); if(version < CIPHERTEXT_CURRENT_VERSION) { - axolotl_log(global_context, AX_LOG_WARNING, "Legacy message: %d", version); - result = AX_ERR_LEGACY_MESSAGE; + signal_log(global_context, SG_LOG_WARNING, "Legacy message: %d", version); + result = SG_ERR_LEGACY_MESSAGE; goto complete; } if(version > CIPHERTEXT_CURRENT_VERSION) { - axolotl_log(global_context, AX_LOG_WARNING, "Unknown version: %d", version); - result = AX_ERR_INVALID_VERSION; + signal_log(global_context, SG_LOG_WARNING, "Unknown version: %d", version); + result = SG_ERR_INVALID_VERSION; goto complete; } message_structure = textsecure__sender_key_distribution_message__unpack(0, message_len, message_data); if(!message_structure) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } @@ -1681,18 +1325,18 @@ int sender_key_distribution_message_deserialize(sender_key_distribution_message || !message_structure->has_iteration || !message_structure->has_chainkey || !message_structure->has_signingkey) { - axolotl_log(global_context, AX_LOG_WARNING, "Incomplete message"); - result = AX_ERR_INVALID_MESSAGE; + signal_log(global_context, SG_LOG_WARNING, "Incomplete message"); + result = SG_ERR_INVALID_MESSAGE; goto complete; } result_message = malloc(sizeof(sender_key_distribution_message)); if(!result_message) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } memset(result_message, 0, sizeof(sender_key_distribution_message)); - AXOLOTL_INIT(result_message, sender_key_distribution_message_destroy); + SIGNAL_INIT(result_message, sender_key_distribution_message_destroy); result_message->base_message.message_type = CIPHERTEXT_SENDERKEY_DISTRIBUTION_TYPE; result_message->base_message.global_context = global_context; @@ -1700,11 +1344,11 @@ int sender_key_distribution_message_deserialize(sender_key_distribution_message result_message->id = message_structure->id; result_message->iteration = message_structure->iteration; - result_message->chain_key = axolotl_buffer_create( + result_message->chain_key = signal_buffer_create( message_structure->chainkey.data, message_structure->chainkey.len); if(!result_message->chain_key) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -1716,9 +1360,9 @@ int sender_key_distribution_message_deserialize(sender_key_distribution_message goto complete; } - result_message->base_message.serialized = axolotl_buffer_create(data, len); + result_message->base_message.serialized = signal_buffer_create(data, len); if(!result_message->base_message.serialized) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -1731,13 +1375,13 @@ complete: } else { if(result_message) { - AXOLOTL_UNREF(result_message); + SIGNAL_UNREF(result_message); } } return result; } -int sender_key_distribution_message_copy(sender_key_distribution_message **message, sender_key_distribution_message *other_message, axolotl_context *global_context) +int sender_key_distribution_message_copy(sender_key_distribution_message **message, sender_key_distribution_message *other_message, signal_context *global_context) { int result = 0; sender_key_distribution_message *result_message = 0; @@ -1747,8 +1391,8 @@ int sender_key_distribution_message_copy(sender_key_distribution_message **messa result = sender_key_distribution_message_deserialize( &result_message, - axolotl_buffer_data(other_message->base_message.serialized), - axolotl_buffer_len(other_message->base_message.serialized), + signal_buffer_data(other_message->base_message.serialized), + signal_buffer_len(other_message->base_message.serialized), global_context); if(result >= 0) { *message = result_message; @@ -1769,7 +1413,7 @@ uint32_t sender_key_distribution_message_get_iteration(sender_key_distribution_m return message->iteration; } -axolotl_buffer *sender_key_distribution_message_get_chain_key(sender_key_distribution_message *message) +signal_buffer *sender_key_distribution_message_get_chain_key(sender_key_distribution_message *message) { assert(message); return message->chain_key; @@ -1781,17 +1425,17 @@ ec_public_key *sender_key_distribution_message_get_signature_key(sender_key_dist return message->signature_key; } -void sender_key_distribution_message_destroy(axolotl_type_base *type) +void sender_key_distribution_message_destroy(signal_type_base *type) { sender_key_distribution_message *message = (sender_key_distribution_message *)type; if(message->base_message.serialized) { - axolotl_buffer_free(message->base_message.serialized); + signal_buffer_free(message->base_message.serialized); } if(message->chain_key) { - axolotl_buffer_free(message->chain_key); + signal_buffer_free(message->chain_key); } - AXOLOTL_UNREF(message->signature_key); + SIGNAL_UNREF(message->signature_key); free(message); } diff --git a/libs/libaxolotl/src/protocol.h b/libs/libaxolotl/src/protocol.h index e149ae84a1..68c3a70be6 100644 --- a/libs/libaxolotl/src/protocol.h +++ b/libs/libaxolotl/src/protocol.h @@ -3,7 +3,7 @@ #include <stdint.h> #include <stddef.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { @@ -16,7 +16,7 @@ extern "C" { #define CIPHERTEXT_UNSUPPORTED_VERSION 1 #define CIPHERTEXT_CURRENT_VERSION 3 -#define CIPHERTEXT_WHISPER_TYPE 2 +#define CIPHERTEXT_SIGNAL_TYPE 2 #define CIPHERTEXT_PREKEY_TYPE 3 #define CIPHERTEXT_SENDERKEY_TYPE 4 #define CIPHERTEXT_SENDERKEY_DISTRIBUTION_TYPE 5 @@ -24,125 +24,101 @@ extern "C" { /* Worst case overhead. Not always accurate, but good enough for padding. */ #define CIPHERTEXT_ENCRYPTED_MESSAGE_OVERHEAD 53 -int key_exchange_message_create(key_exchange_message **message, - uint8_t message_version, uint32_t sequence, uint32_t flags, - ec_public_key *base_key, uint8_t *base_key_signature, - ec_public_key *ratchet_key, ec_public_key *identity_key); - -int key_exchange_message_deserialize(key_exchange_message **message, const uint8_t *data, size_t len, axolotl_context *global_context); - -axolotl_buffer *key_exchange_message_get_serialized(const key_exchange_message *message); - -uint8_t key_exchange_message_get_version(const key_exchange_message *message); -ec_public_key *key_exchange_message_get_base_key(const key_exchange_message *message); -uint8_t *key_exchange_message_get_base_key_signature(key_exchange_message *message); -ec_public_key *key_exchange_message_get_ratchet_key(const key_exchange_message *message); -ec_public_key *key_exchange_message_get_identity_key(const key_exchange_message *message); -int key_exchange_message_has_identity_key(const key_exchange_message *message); -uint8_t key_exchange_message_get_max_version(const key_exchange_message *message); -int key_exchange_message_is_response(const key_exchange_message *message); -int key_exchange_message_is_initiate(const key_exchange_message *message); -int key_exchange_message_is_response_for_simultaneous_initiate(const key_exchange_message *message); -uint32_t key_exchange_message_get_flags(const key_exchange_message *message); -uint32_t key_exchange_message_get_sequence(const key_exchange_message *message); - -void key_exchange_message_destroy(axolotl_type_base *type); - int ciphertext_message_get_type(const ciphertext_message *message); -axolotl_buffer *ciphertext_message_get_serialized(const ciphertext_message *message); +signal_buffer *ciphertext_message_get_serialized(const ciphertext_message *message); -int whisper_message_create(whisper_message **message, uint8_t message_version, +int signal_message_create(signal_message **message, uint8_t message_version, const uint8_t *mac_key, size_t mac_key_len, ec_public_key *sender_ratchet_key, uint32_t counter, uint32_t previous_counter, const uint8_t *ciphertext, size_t ciphertext_len, ec_public_key *sender_identity_key, ec_public_key *receiver_identity_key, - axolotl_context *global_context); + signal_context *global_context); -int whisper_message_deserialize(whisper_message **message, const uint8_t *data, size_t len, - axolotl_context *global_context); +int signal_message_deserialize(signal_message **message, const uint8_t *data, size_t len, + signal_context *global_context); -int whisper_message_copy(whisper_message **message, whisper_message *other_message, axolotl_context *global_context); +int signal_message_copy(signal_message **message, signal_message *other_message, signal_context *global_context); -ec_public_key *whisper_message_get_sender_ratchet_key(const whisper_message *message); +ec_public_key *signal_message_get_sender_ratchet_key(const signal_message *message); -uint8_t whisper_message_get_message_version(const whisper_message *message); +uint8_t signal_message_get_message_version(const signal_message *message); -uint32_t whisper_message_get_counter(const whisper_message *message); +uint32_t signal_message_get_counter(const signal_message *message); -axolotl_buffer *whisper_message_get_body(const whisper_message *message); +signal_buffer *signal_message_get_body(const signal_message *message); /** - * Verify the MAC on the Whisper message. + * Verify the MAC on the Signal message. * * @return 1 if verified, 0 if invalid, negative on error */ -int whisper_message_verify_mac(whisper_message *message, +int signal_message_verify_mac(signal_message *message, uint8_t message_version, ec_public_key *sender_identity_key, ec_public_key *receiver_identity_key, const uint8_t *mac_key, size_t mac_key_len, - axolotl_context *global_context); + signal_context *global_context); -int whisper_message_is_legacy(const uint8_t *data, size_t len); +int signal_message_is_legacy(const uint8_t *data, size_t len); -void whisper_message_destroy(axolotl_type_base *type); +void signal_message_destroy(signal_type_base *type); -int pre_key_whisper_message_create(pre_key_whisper_message **pre_key_message, +int pre_key_signal_message_create(pre_key_signal_message **pre_key_message, uint8_t message_version, uint32_t registration_id, const uint32_t *pre_key_id, uint32_t signed_pre_key_id, ec_public_key *base_key, ec_public_key *identity_key, - whisper_message *message, - axolotl_context *global_context); + signal_message *message, + signal_context *global_context); -int pre_key_whisper_message_deserialize(pre_key_whisper_message **message, +int pre_key_signal_message_deserialize(pre_key_signal_message **message, const uint8_t *data, size_t len, - axolotl_context *global_context); + signal_context *global_context); -int pre_key_whisper_message_copy(pre_key_whisper_message **message, pre_key_whisper_message *other_message, axolotl_context *global_context); +int pre_key_signal_message_copy(pre_key_signal_message **message, pre_key_signal_message *other_message, signal_context *global_context); -uint8_t pre_key_whisper_message_get_message_version(const pre_key_whisper_message *message); -ec_public_key *pre_key_whisper_message_get_identity_key(const pre_key_whisper_message *message); -uint32_t pre_key_whisper_message_get_registration_id(const pre_key_whisper_message *message); -int pre_key_whisper_message_has_pre_key_id(const pre_key_whisper_message *message); -uint32_t pre_key_whisper_message_get_pre_key_id(const pre_key_whisper_message *message); -uint32_t pre_key_whisper_message_get_signed_pre_key_id(const pre_key_whisper_message *message); -ec_public_key *pre_key_whisper_message_get_base_key(const pre_key_whisper_message *message); -whisper_message *pre_key_whisper_message_get_whisper_message(const pre_key_whisper_message *message); +uint8_t pre_key_signal_message_get_message_version(const pre_key_signal_message *message); +ec_public_key *pre_key_signal_message_get_identity_key(const pre_key_signal_message *message); +uint32_t pre_key_signal_message_get_registration_id(const pre_key_signal_message *message); +int pre_key_signal_message_has_pre_key_id(const pre_key_signal_message *message); +uint32_t pre_key_signal_message_get_pre_key_id(const pre_key_signal_message *message); +uint32_t pre_key_signal_message_get_signed_pre_key_id(const pre_key_signal_message *message); +ec_public_key *pre_key_signal_message_get_base_key(const pre_key_signal_message *message); +signal_message *pre_key_signal_message_get_signal_message(const pre_key_signal_message *message); -void pre_key_whisper_message_destroy(axolotl_type_base *type); +void pre_key_signal_message_destroy(signal_type_base *type); int sender_key_message_create(sender_key_message **message, uint32_t key_id, uint32_t iteration, const uint8_t *ciphertext, size_t ciphertext_len, ec_private_key *signature_key, - axolotl_context *global_context); + signal_context *global_context); int sender_key_message_deserialize(sender_key_message **message, const uint8_t *data, size_t len, - axolotl_context *global_context); -int sender_key_message_copy(sender_key_message **message, sender_key_message *other_message, axolotl_context *global_context); + signal_context *global_context); +int sender_key_message_copy(sender_key_message **message, sender_key_message *other_message, signal_context *global_context); uint32_t sender_key_message_get_key_id(sender_key_message *message); uint32_t sender_key_message_get_iteration(sender_key_message *message); -axolotl_buffer *sender_key_message_get_ciphertext(sender_key_message *message); +signal_buffer *sender_key_message_get_ciphertext(sender_key_message *message); int sender_key_message_verify_signature(sender_key_message *message, ec_public_key *signature_key); -void sender_key_message_destroy(axolotl_type_base *type); +void sender_key_message_destroy(signal_type_base *type); int sender_key_distribution_message_create(sender_key_distribution_message **message, uint32_t id, uint32_t iteration, const uint8_t *chain_key, size_t chain_key_len, ec_public_key *signature_key, - axolotl_context *global_context); + signal_context *global_context); int sender_key_distribution_message_deserialize(sender_key_distribution_message **message, const uint8_t *data, size_t len, - axolotl_context *global_context); -int sender_key_distribution_message_copy(sender_key_distribution_message **message, sender_key_distribution_message *other_message, axolotl_context *global_context); + signal_context *global_context); +int sender_key_distribution_message_copy(sender_key_distribution_message **message, sender_key_distribution_message *other_message, signal_context *global_context); uint32_t sender_key_distribution_message_get_id(sender_key_distribution_message *message); uint32_t sender_key_distribution_message_get_iteration(sender_key_distribution_message *message); -axolotl_buffer *sender_key_distribution_message_get_chain_key(sender_key_distribution_message *message); +signal_buffer *sender_key_distribution_message_get_chain_key(sender_key_distribution_message *message); ec_public_key *sender_key_distribution_message_get_signature_key(sender_key_distribution_message *message); -void sender_key_distribution_message_destroy(axolotl_type_base *type); +void sender_key_distribution_message_destroy(signal_type_base *type); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/ratchet.c b/libs/libaxolotl/src/ratchet.c index 8b0dc87bec..bf65ee3e8b 100644..100755 --- a/libs/libaxolotl/src/ratchet.c +++ b/libs/libaxolotl/src/ratchet.c @@ -6,20 +6,21 @@ #include <assert.h> #include "protobuf-c/protobuf-c.h" -#include "axolotl_internal.h" #include "hkdf.h" #include "curve.h" #include "session_state.h" +#include "protocol.h" #include "vpool.h" #include "LocalStorageProtocol.pb-c.h" +#include "signal_protocol_internal.h" #define HASH_OUTPUT_SIZE 32 #define DERIVED_MESSAGE_SECRETS_SIZE 80 #define DERIVED_ROOT_SECRETS_SIZE 64 struct ratchet_chain_key { - axolotl_type_base base; - axolotl_context *global_context; + signal_type_base base; + signal_context *global_context; hkdf_context *kdf; uint8_t *key; size_t key_len; @@ -27,62 +28,62 @@ struct ratchet_chain_key { }; struct ratchet_root_key { - axolotl_type_base base; - axolotl_context *global_context; + signal_type_base base; + signal_context *global_context; hkdf_context *kdf; uint8_t *key; size_t key_len; }; struct ratchet_identity_key_pair { - axolotl_type_base base; + signal_type_base base; ec_public_key *public_key; ec_private_key *private_key; }; -int ratchet_chain_key_create(ratchet_chain_key **chain_key, hkdf_context *kdf, uint8_t *key, size_t key_len, uint32_t index, axolotl_context *global_context) +int ratchet_chain_key_create(ratchet_chain_key **chain_key, hkdf_context *kdf, const uint8_t *key, size_t key_len, uint32_t index, signal_context *global_context) { ratchet_chain_key *result = 0; if(!kdf || !key) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } result = malloc(sizeof(ratchet_chain_key)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - AXOLOTL_INIT(result, ratchet_chain_key_destroy); + SIGNAL_INIT(result, ratchet_chain_key_destroy); result->global_context = global_context; result->kdf = kdf; result->key = malloc(key_len); if(!result->key) { free(result); - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memcpy(result->key, key, key_len); result->key_len = key_len; result->index = index; - AXOLOTL_REF(result->kdf); + SIGNAL_REF(result->kdf); *chain_key = result; return 0; } -int ratchet_chain_key_get_key(const ratchet_chain_key *chain_key, axolotl_buffer **buffer) +int ratchet_chain_key_get_key(const ratchet_chain_key *chain_key, signal_buffer **buffer) { - axolotl_buffer *buf = 0; + signal_buffer *buf = 0; uint8_t *data = 0; - buf = axolotl_buffer_alloc(chain_key->key_len); + buf = signal_buffer_alloc(chain_key->key_len); if(!buf) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - data = axolotl_buffer_data(buf); + data = signal_buffer_data(buf); memcpy(data, chain_key->key, chain_key->key_len); *buffer = buf; @@ -99,7 +100,7 @@ int ratchet_chain_key_get_key_protobuf(const ratchet_chain_key *chain_key, Proto data = malloc(chain_key->key_len); if(!data) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memcpy(data, chain_key->key, chain_key->key_len); @@ -117,38 +118,38 @@ uint32_t ratchet_chain_key_get_index(const ratchet_chain_key *chain_key) ssize_t ratchet_chain_key_get_base_material(const ratchet_chain_key *chain_key, uint8_t **material, const uint8_t *seed, size_t seed_len) { int result = 0; - axolotl_buffer *output_buffer = 0; + signal_buffer *output_buffer = 0; uint8_t *output = 0; size_t output_len = 0; void *hmac_context = 0; - result = axolotl_hmac_sha256_init(chain_key->global_context, &hmac_context, chain_key->key, chain_key->key_len); + result = signal_hmac_sha256_init(chain_key->global_context, &hmac_context, chain_key->key, chain_key->key_len); if(result < 0) { goto complete; } - result = axolotl_hmac_sha256_update(chain_key->global_context, hmac_context, seed, seed_len); + result = signal_hmac_sha256_update(chain_key->global_context, hmac_context, seed, seed_len); if(result < 0) { goto complete; } - result = axolotl_hmac_sha256_final(chain_key->global_context, hmac_context, &output_buffer); + result = signal_hmac_sha256_final(chain_key->global_context, hmac_context, &output_buffer); if(result < 0) { goto complete; } - output_len = axolotl_buffer_len(output_buffer); + output_len = signal_buffer_len(output_buffer); output = malloc(output_len); if(!output) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - memcpy(output, axolotl_buffer_data(output_buffer), output_len); + memcpy(output, signal_buffer_data(output_buffer), output_len); complete: - axolotl_hmac_sha256_cleanup(chain_key->global_context, hmac_context); - axolotl_buffer_free(output_buffer); + signal_hmac_sha256_cleanup(chain_key->global_context, hmac_context); + signal_buffer_free(output_buffer); if(result >= 0) { *material = output; @@ -176,7 +177,7 @@ int ratchet_chain_key_get_message_keys(ratchet_chain_key *chain_key, ratchet_mes result_size = ratchet_chain_key_get_base_material(chain_key, &input_key_material, &message_key_seed, sizeof(message_key_seed)); if(result_size < 0) { result = (int)result_size; - axolotl_log(chain_key->global_context, AX_LOG_WARNING, "ratchet_chain_key_get_base_material failed"); + signal_log(chain_key->global_context, SG_LOG_WARNING, "ratchet_chain_key_get_base_material failed"); goto complete; } input_key_material_len = (size_t)result_size; @@ -191,16 +192,16 @@ int ratchet_chain_key_get_message_keys(ratchet_chain_key *chain_key, ratchet_mes DERIVED_MESSAGE_SECRETS_SIZE); if(result_size < 0) { result = (int)result_size; - axolotl_log(chain_key->global_context, AX_LOG_WARNING, "hkdf_derive_secrets failed"); + signal_log(chain_key->global_context, SG_LOG_WARNING, "hkdf_derive_secrets failed"); goto complete; } key_material_data_len = (size_t)result_size; if(key_material_data_len != RATCHET_CIPHER_KEY_LENGTH + RATCHET_MAC_KEY_LENGTH + RATCHET_IV_LENGTH) { - axolotl_log(chain_key->global_context, AX_LOG_WARNING, + signal_log(chain_key->global_context, SG_LOG_WARNING, "key_material_data length mismatch: %d != %d", key_material_data_len, (RATCHET_CIPHER_KEY_LENGTH + RATCHET_MAC_KEY_LENGTH + RATCHET_IV_LENGTH)); - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } @@ -235,7 +236,7 @@ int ratchet_chain_key_create_next(const ratchet_chain_key *chain_key, ratchet_ch result_size = ratchet_chain_key_get_base_material(chain_key, &next_key, &chain_key_seed, sizeof(chain_key_seed)); if(result_size < 0) { result = (int)result_size; - axolotl_log(chain_key->global_context, AX_LOG_WARNING, "ratchet_chain_key_get_base_material failed"); + signal_log(chain_key->global_context, SG_LOG_WARNING, "ratchet_chain_key_get_base_material failed"); goto complete; } next_key_len = (size_t)result_size; @@ -255,42 +256,42 @@ complete: return result; } -void ratchet_chain_key_destroy(axolotl_type_base *type) +void ratchet_chain_key_destroy(signal_type_base *type) { ratchet_chain_key *chain_key = (ratchet_chain_key *)type; - AXOLOTL_UNREF(chain_key->kdf); + SIGNAL_UNREF(chain_key->kdf); if(chain_key->key) { - axolotl_explicit_bzero(chain_key->key, chain_key->key_len); + signal_explicit_bzero(chain_key->key, chain_key->key_len); free(chain_key->key); } free(chain_key); } -int ratchet_root_key_create(ratchet_root_key **root_key, hkdf_context *kdf, const uint8_t *key, size_t key_len, axolotl_context *global_context) +int ratchet_root_key_create(ratchet_root_key **root_key, hkdf_context *kdf, const uint8_t *key, size_t key_len, signal_context *global_context) { ratchet_root_key *result = 0; if(!kdf || !key) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } result = malloc(sizeof(ratchet_root_key)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - AXOLOTL_INIT(result, ratchet_root_key_destroy); + SIGNAL_INIT(result, ratchet_root_key_destroy); result->global_context = global_context; result->kdf = kdf; result->key = malloc(key_len); if(!result->key) { free(result); - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memcpy(result->key, key, key_len); result->key_len = key_len; - AXOLOTL_REF(result->kdf); + SIGNAL_REF(result->kdf); *root_key = result; return 0; @@ -311,12 +312,12 @@ int ratchet_root_key_create_chain(ratchet_root_key *root_key, ratchet_chain_key *new_chain_key_result = 0; if(!their_ratchet_key || !our_ratchet_key_private) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } result = curve_calculate_agreement(&shared_secret, their_ratchet_key, our_ratchet_key_private); if(result < 0) { - axolotl_log(root_key->global_context, AX_LOG_WARNING, "curve_calculate_agreement failed"); + signal_log(root_key->global_context, SG_LOG_WARNING, "curve_calculate_agreement failed"); goto complete; } shared_secret_len = (size_t)result; @@ -328,12 +329,12 @@ int ratchet_root_key_create_chain(ratchet_root_key *root_key, DERIVED_ROOT_SECRETS_SIZE); if(result_size < 0) { result = (int)result_size; - axolotl_log(root_key->global_context, AX_LOG_WARNING, "hkdf_derive_secrets failed"); + signal_log(root_key->global_context, SG_LOG_WARNING, "hkdf_derive_secrets failed"); goto complete; } else if(result_size != DERIVED_ROOT_SECRETS_SIZE) { - result = AX_ERR_UNKNOWN; - axolotl_log(root_key->global_context, AX_LOG_WARNING, "hkdf_derive_secrets size mismatch"); + result = SG_ERR_UNKNOWN; + signal_log(root_key->global_context, SG_LOG_WARNING, "hkdf_derive_secrets size mismatch"); goto complete; } @@ -341,7 +342,7 @@ int ratchet_root_key_create_chain(ratchet_root_key *root_key, derived_secret, 32, root_key->global_context); if(result < 0) { - axolotl_log(root_key->global_context, AX_LOG_WARNING, "ratchet_root_key_create failed"); + signal_log(root_key->global_context, SG_LOG_WARNING, "ratchet_root_key_create failed"); goto complete; } @@ -349,7 +350,7 @@ int ratchet_root_key_create_chain(ratchet_root_key *root_key, derived_secret + 32, 32, 0, root_key->global_context); if(result < 0) { - axolotl_log(root_key->global_context, AX_LOG_WARNING, "ratchet_chain_key_create failed"); + signal_log(root_key->global_context, SG_LOG_WARNING, "ratchet_chain_key_create failed"); goto complete; } @@ -362,10 +363,10 @@ complete: } if(result < 0) { if(new_root_key_result) { - AXOLOTL_UNREF(new_root_key_result); + SIGNAL_UNREF(new_root_key_result); } if(new_chain_key_result) { - AXOLOTL_UNREF(new_chain_key_result); + SIGNAL_UNREF(new_chain_key_result); } return result; } @@ -376,19 +377,19 @@ complete: } } -int ratchet_root_key_get_key(ratchet_root_key *root_key, axolotl_buffer **buffer) +int ratchet_root_key_get_key(ratchet_root_key *root_key, signal_buffer **buffer) { - axolotl_buffer *buf = 0; + signal_buffer *buf = 0; uint8_t *data = 0; assert(root_key); - buf = axolotl_buffer_alloc(root_key->key_len); + buf = signal_buffer_alloc(root_key->key_len); if(!buf) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - data = axolotl_buffer_data(buf); + data = signal_buffer_data(buf); memcpy(data, root_key->key, root_key->key_len); *buffer = buf; @@ -405,7 +406,7 @@ int ratchet_root_key_get_key_protobuf(const ratchet_root_key *root_key, Protobuf data = malloc(root_key->key_len); if(!data) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memcpy(data, root_key->key, root_key->key_len); @@ -438,17 +439,17 @@ int ratchet_root_key_compare(const ratchet_root_key *key1, const ratchet_root_ke return 1; } else { - return axolotl_constant_memcmp(key1->key, key2->key, key1->key_len); + return signal_constant_memcmp(key1->key, key2->key, key1->key_len); } } } -void ratchet_root_key_destroy(axolotl_type_base *type) +void ratchet_root_key_destroy(signal_type_base *type) { ratchet_root_key *root_key = (ratchet_root_key *)type; - AXOLOTL_UNREF(root_key->kdf); + SIGNAL_UNREF(root_key->kdf); if(root_key->key) { - axolotl_explicit_bzero(root_key->key, root_key->key_len); + signal_explicit_bzero(root_key->key, root_key->key_len); free(root_key->key); } free(root_key); @@ -461,12 +462,12 @@ int ratchet_identity_key_pair_create( { ratchet_identity_key_pair *result = malloc(sizeof(ratchet_identity_key_pair)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - AXOLOTL_INIT(result, ratchet_identity_key_pair_destroy); - AXOLOTL_REF(public_key); - AXOLOTL_REF(private_key); + SIGNAL_INIT(result, ratchet_identity_key_pair_destroy); + SIGNAL_REF(public_key); + SIGNAL_REF(private_key); result->public_key = public_key; result->private_key = private_key; @@ -475,15 +476,20 @@ int ratchet_identity_key_pair_create( return 0; } -int ratchet_identity_key_pair_serialize(axolotl_buffer **buffer, const ratchet_identity_key_pair *key_pair) +int ratchet_identity_key_pair_serialize(signal_buffer **buffer, const ratchet_identity_key_pair *key_pair) { int result = 0; size_t result_size = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; Textsecure__IdentityKeyPairStructure key_structure = TEXTSECURE__IDENTITY_KEY_PAIR_STRUCTURE__INIT; size_t len = 0; uint8_t *data = 0; + if(!key_pair) { + result = SG_ERR_INVAL; + goto complete; + } + result = ec_public_key_serialize_protobuf(&key_structure.publickey, key_pair->public_key); if(result < 0) { goto complete; @@ -497,17 +503,17 @@ int ratchet_identity_key_pair_serialize(axolotl_buffer **buffer, const ratchet_i key_structure.has_privatekey = 1; len = textsecure__identity_key_pair_structure__get_packed_size(&key_structure); - result_buf = axolotl_buffer_alloc(len); + result_buf = signal_buffer_alloc(len); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); result_size = textsecure__identity_key_pair_structure__pack(&key_structure, data); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } @@ -526,7 +532,7 @@ complete: return result; } -int ratchet_identity_key_pair_deserialize(ratchet_identity_key_pair **key_pair, const uint8_t *data, size_t len, axolotl_context *global_context) +int ratchet_identity_key_pair_deserialize(ratchet_identity_key_pair **key_pair, const uint8_t *data, size_t len, signal_context *global_context) { int result = 0; ec_public_key *public_key = 0; @@ -536,12 +542,12 @@ int ratchet_identity_key_pair_deserialize(ratchet_identity_key_pair **key_pair, key_structure = textsecure__identity_key_pair_structure__unpack(0, len, data); if(!key_structure) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } if(!key_structure->has_publickey || !key_structure->has_privatekey) { - result = AX_ERR_INVALID_KEY; + result = SG_ERR_INVALID_KEY; goto complete; } @@ -567,8 +573,8 @@ int ratchet_identity_key_pair_deserialize(ratchet_identity_key_pair **key_pair, public_key, private_key); complete: - AXOLOTL_UNREF(public_key); - AXOLOTL_UNREF(private_key); + SIGNAL_UNREF(public_key); + SIGNAL_UNREF(private_key); if(key_structure) { textsecure__identity_key_pair_structure__free_unpacked(key_structure, 0); } @@ -592,17 +598,17 @@ ec_private_key *ratchet_identity_key_pair_get_private(const ratchet_identity_key return key_pair->private_key; } -void ratchet_identity_key_pair_destroy(axolotl_type_base *type) +void ratchet_identity_key_pair_destroy(signal_type_base *type) { ratchet_identity_key_pair *key_pair = (ratchet_identity_key_pair *)type; - AXOLOTL_UNREF(key_pair->public_key); - AXOLOTL_UNREF(key_pair->private_key); + SIGNAL_UNREF(key_pair->public_key); + SIGNAL_UNREF(key_pair->private_key); free(key_pair); } -struct symmetric_axolotl_parameters +struct symmetric_signal_protocol_parameters { - axolotl_type_base base; + signal_type_base base; ratchet_identity_key_pair *our_identity_key; ec_key_pair *our_base_key; ec_key_pair *our_ratchet_key; @@ -611,9 +617,9 @@ struct symmetric_axolotl_parameters ec_public_key *their_identity_key; }; -struct alice_axolotl_parameters +struct alice_signal_protocol_parameters { - axolotl_type_base base; + signal_type_base base; ratchet_identity_key_pair *our_identity_key; ec_key_pair *our_base_key; ec_public_key *their_identity_key; @@ -622,9 +628,9 @@ struct alice_axolotl_parameters ec_public_key *their_ratchet_key; }; -struct bob_axolotl_parameters +struct bob_signal_protocol_parameters { - axolotl_type_base base; + signal_type_base base; ratchet_identity_key_pair *our_identity_key; ec_key_pair *our_signed_pre_key; ec_key_pair *our_one_time_pre_key; /* optional */ @@ -633,8 +639,8 @@ struct bob_axolotl_parameters ec_public_key *their_base_key; }; -int symmetric_axolotl_parameters_create( - symmetric_axolotl_parameters **parameters, +int symmetric_signal_protocol_parameters_create( + symmetric_signal_protocol_parameters **parameters, ratchet_identity_key_pair *our_identity_key, ec_key_pair *our_base_key, ec_key_pair *our_ratchet_key, @@ -642,27 +648,27 @@ int symmetric_axolotl_parameters_create( ec_public_key *their_ratchet_key, ec_public_key *their_identity_key) { - symmetric_axolotl_parameters *result = 0; + symmetric_signal_protocol_parameters *result = 0; if(!our_identity_key || !our_base_key || !our_ratchet_key || !their_base_key || !their_ratchet_key || !their_identity_key) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } - result = malloc(sizeof(symmetric_axolotl_parameters)); + result = malloc(sizeof(symmetric_signal_protocol_parameters)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - memset(result, 0, sizeof(symmetric_axolotl_parameters)); + memset(result, 0, sizeof(symmetric_signal_protocol_parameters)); - AXOLOTL_INIT(result, symmetric_axolotl_parameters_destroy); - AXOLOTL_REF(our_identity_key); - AXOLOTL_REF(our_base_key); - AXOLOTL_REF(our_ratchet_key); - AXOLOTL_REF(their_base_key); - AXOLOTL_REF(their_ratchet_key); - AXOLOTL_REF(their_identity_key); + SIGNAL_INIT(result, symmetric_signal_protocol_parameters_destroy); + SIGNAL_REF(our_identity_key); + SIGNAL_REF(our_base_key); + SIGNAL_REF(our_ratchet_key); + SIGNAL_REF(their_base_key); + SIGNAL_REF(their_ratchet_key); + SIGNAL_REF(their_identity_key); result->our_identity_key = our_identity_key; result->our_base_key = our_base_key; result->our_ratchet_key = our_ratchet_key; @@ -674,58 +680,58 @@ int symmetric_axolotl_parameters_create( return 0; } -ratchet_identity_key_pair *symmetric_axolotl_parameters_get_our_identity_key(const symmetric_axolotl_parameters *parameters) +ratchet_identity_key_pair *symmetric_signal_protocol_parameters_get_our_identity_key(const symmetric_signal_protocol_parameters *parameters) { assert(parameters); return parameters->our_identity_key; } -ec_key_pair *symmetric_axolotl_parameters_get_our_base_key(const symmetric_axolotl_parameters *parameters) +ec_key_pair *symmetric_signal_protocol_parameters_get_our_base_key(const symmetric_signal_protocol_parameters *parameters) { assert(parameters); return parameters->our_base_key; } -ec_key_pair *symmetric_axolotl_parameters_get_our_ratchet_key(const symmetric_axolotl_parameters *parameters) +ec_key_pair *symmetric_signal_protocol_parameters_get_our_ratchet_key(const symmetric_signal_protocol_parameters *parameters) { assert(parameters); return parameters->our_ratchet_key; } -ec_public_key *symmetric_axolotl_parameters_get_their_base_key(const symmetric_axolotl_parameters *parameters) +ec_public_key *symmetric_signal_protocol_parameters_get_their_base_key(const symmetric_signal_protocol_parameters *parameters) { assert(parameters); return parameters->their_base_key; } -ec_public_key *symmetric_axolotl_parameters_get_their_ratchet_key(const symmetric_axolotl_parameters *parameters) +ec_public_key *symmetric_signal_protocol_parameters_get_their_ratchet_key(const symmetric_signal_protocol_parameters *parameters) { assert(parameters); return parameters->their_ratchet_key; } -ec_public_key *symmetric_axolotl_parameters_get_their_identity_key(const symmetric_axolotl_parameters *parameters) +ec_public_key *symmetric_signal_protocol_parameters_get_their_identity_key(const symmetric_signal_protocol_parameters *parameters) { assert(parameters); return parameters->their_identity_key; } -void symmetric_axolotl_parameters_destroy(axolotl_type_base *type) +void symmetric_signal_protocol_parameters_destroy(signal_type_base *type) { - symmetric_axolotl_parameters *parameters = (symmetric_axolotl_parameters *)type; + symmetric_signal_protocol_parameters *parameters = (symmetric_signal_protocol_parameters *)type; - AXOLOTL_UNREF(parameters->our_identity_key); - AXOLOTL_UNREF(parameters->our_base_key); - AXOLOTL_UNREF(parameters->our_ratchet_key); - AXOLOTL_UNREF(parameters->their_base_key); - AXOLOTL_UNREF(parameters->their_ratchet_key); - AXOLOTL_UNREF(parameters->their_identity_key); + SIGNAL_UNREF(parameters->our_identity_key); + SIGNAL_UNREF(parameters->our_base_key); + SIGNAL_UNREF(parameters->our_ratchet_key); + SIGNAL_UNREF(parameters->their_base_key); + SIGNAL_UNREF(parameters->their_ratchet_key); + SIGNAL_UNREF(parameters->their_identity_key); free(parameters); } -int alice_axolotl_parameters_create( - alice_axolotl_parameters **parameters, +int alice_signal_protocol_parameters_create( + alice_signal_protocol_parameters **parameters, ratchet_identity_key_pair *our_identity_key, ec_key_pair *our_base_key, ec_public_key *their_identity_key, @@ -733,27 +739,27 @@ int alice_axolotl_parameters_create( ec_public_key *their_one_time_pre_key, ec_public_key *their_ratchet_key) { - alice_axolotl_parameters *result = 0; + alice_signal_protocol_parameters *result = 0; /* Only "their_one_time_pre_key" is allowed to be null */ if(!our_identity_key || !our_base_key || !their_identity_key || !their_signed_pre_key || !their_ratchet_key) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } - result = malloc(sizeof(alice_axolotl_parameters)); + result = malloc(sizeof(alice_signal_protocol_parameters)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - memset(result, 0, sizeof(alice_axolotl_parameters)); + memset(result, 0, sizeof(alice_signal_protocol_parameters)); - AXOLOTL_INIT(result, alice_axolotl_parameters_destroy); - AXOLOTL_REF(our_identity_key); - AXOLOTL_REF(our_base_key); - AXOLOTL_REF(their_identity_key); - AXOLOTL_REF(their_signed_pre_key); - AXOLOTL_REF(their_ratchet_key); + SIGNAL_INIT(result, alice_signal_protocol_parameters_destroy); + SIGNAL_REF(our_identity_key); + SIGNAL_REF(our_base_key); + SIGNAL_REF(their_identity_key); + SIGNAL_REF(their_signed_pre_key); + SIGNAL_REF(their_ratchet_key); result->our_identity_key = our_identity_key; result->our_base_key = our_base_key; result->their_identity_key = their_identity_key; @@ -761,7 +767,7 @@ int alice_axolotl_parameters_create( result->their_ratchet_key = their_ratchet_key; if(their_one_time_pre_key) { - AXOLOTL_REF(their_one_time_pre_key); + SIGNAL_REF(their_one_time_pre_key); result->their_one_time_pre_key = their_one_time_pre_key; } @@ -769,25 +775,25 @@ int alice_axolotl_parameters_create( return 0; } -void alice_axolotl_parameters_destroy(axolotl_type_base *type) +void alice_signal_protocol_parameters_destroy(signal_type_base *type) { - alice_axolotl_parameters *parameters = (alice_axolotl_parameters *)type; + alice_signal_protocol_parameters *parameters = (alice_signal_protocol_parameters *)type; - AXOLOTL_UNREF(parameters->our_identity_key); - AXOLOTL_UNREF(parameters->our_base_key); - AXOLOTL_UNREF(parameters->their_identity_key); - AXOLOTL_UNREF(parameters->their_signed_pre_key); - AXOLOTL_UNREF(parameters->their_ratchet_key); + SIGNAL_UNREF(parameters->our_identity_key); + SIGNAL_UNREF(parameters->our_base_key); + SIGNAL_UNREF(parameters->their_identity_key); + SIGNAL_UNREF(parameters->their_signed_pre_key); + SIGNAL_UNREF(parameters->their_ratchet_key); if(parameters->their_one_time_pre_key) { - AXOLOTL_UNREF(parameters->their_one_time_pre_key); + SIGNAL_UNREF(parameters->their_one_time_pre_key); } free(parameters); } -int bob_axolotl_parameters_create( - bob_axolotl_parameters **parameters, +int bob_signal_protocol_parameters_create( + bob_signal_protocol_parameters **parameters, ratchet_identity_key_pair *our_identity_key, ec_key_pair *our_signed_pre_key, ec_key_pair *our_one_time_pre_key, @@ -795,27 +801,27 @@ int bob_axolotl_parameters_create( ec_public_key *their_identity_key, ec_public_key *their_base_key) { - bob_axolotl_parameters *result = 0; + bob_signal_protocol_parameters *result = 0; /* Only "our_one_time_pre_key" is allowed to be null */ if(!our_identity_key || !our_signed_pre_key || !our_ratchet_key || !their_identity_key || !their_base_key) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } - result = malloc(sizeof(bob_axolotl_parameters)); + result = malloc(sizeof(bob_signal_protocol_parameters)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - memset(result, 0, sizeof(bob_axolotl_parameters)); + memset(result, 0, sizeof(bob_signal_protocol_parameters)); - AXOLOTL_INIT(result, bob_axolotl_parameters_destroy); - AXOLOTL_REF(our_identity_key); - AXOLOTL_REF(our_signed_pre_key); - AXOLOTL_REF(our_ratchet_key); - AXOLOTL_REF(their_identity_key); - AXOLOTL_REF(their_base_key); + SIGNAL_INIT(result, bob_signal_protocol_parameters_destroy); + SIGNAL_REF(our_identity_key); + SIGNAL_REF(our_signed_pre_key); + SIGNAL_REF(our_ratchet_key); + SIGNAL_REF(their_identity_key); + SIGNAL_REF(their_base_key); result->our_identity_key = our_identity_key; result->our_signed_pre_key = our_signed_pre_key; result->our_ratchet_key = our_ratchet_key; @@ -823,7 +829,7 @@ int bob_axolotl_parameters_create( result->their_base_key = their_base_key; if(our_one_time_pre_key) { - AXOLOTL_REF(our_one_time_pre_key); + SIGNAL_REF(our_one_time_pre_key); result->our_one_time_pre_key = our_one_time_pre_key; } @@ -831,25 +837,25 @@ int bob_axolotl_parameters_create( return 0; } -void bob_axolotl_parameters_destroy(axolotl_type_base *type) +void bob_signal_protocol_parameters_destroy(signal_type_base *type) { - bob_axolotl_parameters *parameters = (bob_axolotl_parameters *)type; + bob_signal_protocol_parameters *parameters = (bob_signal_protocol_parameters *)type; - AXOLOTL_UNREF(parameters->our_identity_key); - AXOLOTL_UNREF(parameters->our_signed_pre_key); - AXOLOTL_UNREF(parameters->our_ratchet_key); - AXOLOTL_UNREF(parameters->their_identity_key); - AXOLOTL_UNREF(parameters->their_base_key); + SIGNAL_UNREF(parameters->our_identity_key); + SIGNAL_UNREF(parameters->our_signed_pre_key); + SIGNAL_UNREF(parameters->our_ratchet_key); + SIGNAL_UNREF(parameters->their_identity_key); + SIGNAL_UNREF(parameters->their_base_key); if(parameters->our_one_time_pre_key) { - AXOLOTL_UNREF(parameters->our_one_time_pre_key); + SIGNAL_UNREF(parameters->our_one_time_pre_key); } free(parameters); } int ratcheting_session_calculate_derived_keys(ratchet_root_key **root_key, ratchet_chain_key **chain_key, - uint32_t version, uint8_t *secret, size_t secret_len, axolotl_context *global_context) + uint8_t *secret, size_t secret_len, signal_context *global_context) { int result = 0; ssize_t result_size = 0; @@ -860,7 +866,7 @@ int ratcheting_session_calculate_derived_keys(ratchet_root_key **root_key, ratch uint8_t salt[HASH_OUTPUT_SIZE]; static const char key_info[] = "WhisperText"; - result = hkdf_create(&kdf, (int)version, global_context); + result = hkdf_create(&kdf, 3, global_context); if(result < 0) { goto complete; } @@ -872,7 +878,7 @@ int ratcheting_session_calculate_derived_keys(ratchet_root_key **root_key, ratch salt, sizeof(salt), (uint8_t *)key_info, sizeof(key_info) - 1, 64); if(result_size != 64) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } @@ -888,7 +894,7 @@ int ratcheting_session_calculate_derived_keys(ratchet_root_key **root_key, ratch complete: if(kdf) { - AXOLOTL_UNREF(kdf); + SIGNAL_UNREF(kdf); } if(output) { free(output); @@ -896,10 +902,10 @@ complete: if(result < 0) { if(root_key_result) { - AXOLOTL_UNREF(root_key_result); + SIGNAL_UNREF(root_key_result); } if(chain_key_result) { - AXOLOTL_UNREF(chain_key_result); + SIGNAL_UNREF(chain_key_result); } } else { @@ -910,7 +916,7 @@ complete: return result; } -int ratcheting_session_symmetric_is_alice(symmetric_axolotl_parameters *parameters) +int ratcheting_session_symmetric_is_alice(symmetric_signal_protocol_parameters *parameters) { //FIXME Java code checks if our_base_key < their_base_key // This comparison may not return the same result. However, we should find @@ -921,9 +927,9 @@ int ratcheting_session_symmetric_is_alice(symmetric_axolotl_parameters *paramete } int ratcheting_session_symmetric_initialize( - session_state *state, uint32_t version, - symmetric_axolotl_parameters *parameters, - axolotl_context *global_context) + session_state *state, + symmetric_signal_protocol_parameters *parameters, + signal_context *global_context) { int result = 0; @@ -932,8 +938,8 @@ int ratcheting_session_symmetric_initialize( assert(global_context); if(ratcheting_session_symmetric_is_alice(parameters)) { - alice_axolotl_parameters *alice_parameters = 0; - result = alice_axolotl_parameters_create(&alice_parameters, + alice_signal_protocol_parameters *alice_parameters = 0; + result = alice_signal_protocol_parameters_create(&alice_parameters, parameters->our_identity_key, parameters->our_base_key, parameters->their_identity_key, @@ -941,15 +947,15 @@ int ratcheting_session_symmetric_initialize( 0, parameters->their_ratchet_key); if(result >= 0) { - result = ratcheting_session_alice_initialize(state, version, alice_parameters, global_context); + result = ratcheting_session_alice_initialize(state, alice_parameters, global_context); } if(alice_parameters) { - AXOLOTL_UNREF(alice_parameters); + SIGNAL_UNREF(alice_parameters); } } else { - bob_axolotl_parameters *bob_parameters = 0; - result = bob_axolotl_parameters_create(&bob_parameters, + bob_signal_protocol_parameters *bob_parameters = 0; + result = bob_signal_protocol_parameters_create(&bob_parameters, parameters->our_identity_key, parameters->our_base_key, 0, @@ -957,19 +963,19 @@ int ratcheting_session_symmetric_initialize( parameters->their_identity_key, parameters->their_base_key); if(result >= 0) { - result = ratcheting_session_bob_initialize(state, version, bob_parameters, global_context); + result = ratcheting_session_bob_initialize(state, bob_parameters, global_context); } if(bob_parameters) { - AXOLOTL_UNREF(bob_parameters); + SIGNAL_UNREF(bob_parameters); } } return result; } int ratcheting_session_alice_initialize( - session_state *state, uint32_t version, - alice_axolotl_parameters *parameters, - axolotl_context *global_context) + session_state *state, + alice_signal_protocol_parameters *parameters, + signal_context *global_context) { int result = 0; uint8_t *agreement = 0; @@ -982,6 +988,7 @@ int ratcheting_session_alice_initialize( struct vpool vp; uint8_t *secret = 0; size_t secret_len = 0; + uint8_t discontinuity_data[32]; assert(state); assert(parameters); @@ -994,13 +1001,10 @@ int ratcheting_session_alice_initialize( goto complete; } - if(version >= 3) { - uint8_t discontinuity_data[32]; - memset(discontinuity_data, 0xFF, sizeof(discontinuity_data)); - if(!vpool_insert(&vp, vpool_get_length(&vp), discontinuity_data, sizeof(discontinuity_data))) { - result = AX_ERR_NOMEM; - goto complete; - } + memset(discontinuity_data, 0xFF, sizeof(discontinuity_data)); + if(!vpool_insert(&vp, vpool_get_length(&vp), discontinuity_data, sizeof(discontinuity_data))) { + result = SG_ERR_NOMEM; + goto complete; } agreement_len = curve_calculate_agreement(&agreement, @@ -1013,7 +1017,7 @@ int ratcheting_session_alice_initialize( free(agreement); agreement = 0; agreement_len = 0; } else { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -1027,7 +1031,7 @@ int ratcheting_session_alice_initialize( free(agreement); agreement = 0; agreement_len = 0; } else { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -1041,11 +1045,11 @@ int ratcheting_session_alice_initialize( free(agreement); agreement = 0; agreement_len = 0; } else { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - if(version >= 3 && parameters->their_one_time_pre_key) { + if(parameters->their_one_time_pre_key) { agreement_len = curve_calculate_agreement(&agreement, parameters->their_one_time_pre_key, ec_key_pair_get_private(parameters->our_base_key)); if(agreement_len < 0) { @@ -1056,20 +1060,20 @@ int ratcheting_session_alice_initialize( free(agreement); agreement = 0; agreement_len = 0; } else { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } } if(vpool_is_empty(&vp)) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } secret = vpool_get_buf(&vp); secret_len = vpool_get_length(&vp); - result = ratcheting_session_calculate_derived_keys(&derived_root, &derived_chain, version, secret, secret_len, global_context); + result = ratcheting_session_calculate_derived_keys(&derived_root, &derived_chain, secret, secret_len, global_context); if(result < 0) { goto complete; } @@ -1084,7 +1088,7 @@ int ratcheting_session_alice_initialize( complete: if(result >= 0) { - session_state_set_session_version(state, version); + session_state_set_session_version(state, CIPHERTEXT_CURRENT_VERSION); session_state_set_remote_identity_key(state, parameters->their_identity_key); session_state_set_local_identity_key(state, parameters->our_identity_key->public_key); session_state_add_receiver_chain(state, parameters->their_ratchet_key, derived_chain); @@ -1097,28 +1101,28 @@ complete: free(agreement); } if(sending_ratchet_key) { - AXOLOTL_UNREF(sending_ratchet_key); + SIGNAL_UNREF(sending_ratchet_key); } if(derived_root) { - AXOLOTL_UNREF(derived_root); + SIGNAL_UNREF(derived_root); } if(derived_chain) { - AXOLOTL_UNREF(derived_chain); + SIGNAL_UNREF(derived_chain); } if(sending_chain_root) { - AXOLOTL_UNREF(sending_chain_root); + SIGNAL_UNREF(sending_chain_root); } if(sending_chain_key) { - AXOLOTL_UNREF(sending_chain_key); + SIGNAL_UNREF(sending_chain_key); } return result; } int ratcheting_session_bob_initialize( - session_state *state, uint32_t version, - bob_axolotl_parameters *parameters, - axolotl_context *global_context) + session_state *state, + bob_signal_protocol_parameters *parameters, + signal_context *global_context) { int result = 0; uint8_t *agreement = 0; @@ -1128,7 +1132,7 @@ int ratcheting_session_bob_initialize( struct vpool vp; uint8_t *secret = 0; size_t secret_len = 0; - + uint8_t discontinuity_data[32]; assert(state); assert(parameters); @@ -1136,13 +1140,10 @@ int ratcheting_session_bob_initialize( vpool_init(&vp, 1024, 0); - if(version >= 3) { - uint8_t discontinuity_data[32]; - memset(discontinuity_data, 0xFF, sizeof(discontinuity_data)); - if(!vpool_insert(&vp, vpool_get_length(&vp), discontinuity_data, sizeof(discontinuity_data))) { - result = AX_ERR_NOMEM; - goto complete; - } + memset(discontinuity_data, 0xFF, sizeof(discontinuity_data)); + if(!vpool_insert(&vp, vpool_get_length(&vp), discontinuity_data, sizeof(discontinuity_data))) { + result = SG_ERR_NOMEM; + goto complete; } agreement_len = curve_calculate_agreement(&agreement, @@ -1155,7 +1156,7 @@ int ratcheting_session_bob_initialize( free(agreement); agreement = 0; agreement_len = 0; } else { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -1169,7 +1170,7 @@ int ratcheting_session_bob_initialize( free(agreement); agreement = 0; agreement_len = 0; } else { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -1183,11 +1184,11 @@ int ratcheting_session_bob_initialize( free(agreement); agreement = 0; agreement_len = 0; } else { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - if(version >= 3 && parameters->our_one_time_pre_key) { + if(parameters->our_one_time_pre_key) { agreement_len = curve_calculate_agreement(&agreement, parameters->their_base_key, ec_key_pair_get_private(parameters->our_one_time_pre_key)); if(agreement_len < 0) { @@ -1198,24 +1199,24 @@ int ratcheting_session_bob_initialize( free(agreement); agreement = 0; agreement_len = 0; } else { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } } if(vpool_is_empty(&vp)) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } secret = vpool_get_buf(&vp); secret_len = vpool_get_length(&vp); - result = ratcheting_session_calculate_derived_keys(&derived_root, &derived_chain, version, secret, secret_len, global_context); + result = ratcheting_session_calculate_derived_keys(&derived_root, &derived_chain, secret, secret_len, global_context); complete: if(result >= 0) { - session_state_set_session_version(state, version); + session_state_set_session_version(state, CIPHERTEXT_CURRENT_VERSION); session_state_set_remote_identity_key(state, parameters->their_identity_key); session_state_set_local_identity_key(state, parameters->our_identity_key->public_key); session_state_set_sender_chain(state, parameters->our_ratchet_key, derived_chain); @@ -1227,10 +1228,10 @@ complete: free(agreement); } if(derived_root) { - AXOLOTL_UNREF(derived_root); + SIGNAL_UNREF(derived_root); } if(derived_chain) { - AXOLOTL_UNREF(derived_chain); + SIGNAL_UNREF(derived_chain); } return result; diff --git a/libs/libaxolotl/src/ratchet.h b/libs/libaxolotl/src/ratchet.h index 1534b3c24c..e42c98a61e 100644 --- a/libs/libaxolotl/src/ratchet.h +++ b/libs/libaxolotl/src/ratchet.h @@ -3,85 +3,85 @@ #include <stdint.h> #include <stddef.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { #endif int ratchet_chain_key_create(ratchet_chain_key **chain_key, hkdf_context *kdf, - uint8_t *key, size_t key_len, uint32_t index, - axolotl_context *global_context); -int ratchet_chain_key_get_key(const ratchet_chain_key *chain_key, axolotl_buffer **buffer); + const uint8_t *key, size_t key_len, uint32_t index, + signal_context *global_context); +int ratchet_chain_key_get_key(const ratchet_chain_key *chain_key, signal_buffer **buffer); uint32_t ratchet_chain_key_get_index(const ratchet_chain_key *chain_key); int ratchet_chain_key_get_message_keys(ratchet_chain_key *chain_key, ratchet_message_keys *message_keys); int ratchet_chain_key_create_next(const ratchet_chain_key *chain_key, ratchet_chain_key **next_chain_key); -void ratchet_chain_key_destroy(axolotl_type_base *type); +void ratchet_chain_key_destroy(signal_type_base *type); int ratchet_root_key_create(ratchet_root_key **root_key, hkdf_context *kdf, const uint8_t *key, size_t key_len, - axolotl_context *global_context); + signal_context *global_context); int ratchet_root_key_create_chain(ratchet_root_key *root_key, ratchet_root_key **new_root_key, ratchet_chain_key **new_chain_key, ec_public_key *their_ratchet_key, ec_private_key *our_ratchet_key_private); -int ratchet_root_key_get_key(ratchet_root_key *root_key, axolotl_buffer **buffer); +int ratchet_root_key_get_key(ratchet_root_key *root_key, signal_buffer **buffer); int ratchet_root_key_compare(const ratchet_root_key *key1, const ratchet_root_key *key2); -void ratchet_root_key_destroy(axolotl_type_base *type); +void ratchet_root_key_destroy(signal_type_base *type); int ratchet_identity_key_pair_create( ratchet_identity_key_pair **key_pair, ec_public_key *public_key, ec_private_key *private_key); -int ratchet_identity_key_pair_serialize(axolotl_buffer **buffer, const ratchet_identity_key_pair *key_pair); -int ratchet_identity_key_pair_deserialize(ratchet_identity_key_pair **key_pair, const uint8_t *data, size_t len, axolotl_context *global_context); +int ratchet_identity_key_pair_serialize(signal_buffer **buffer, const ratchet_identity_key_pair *key_pair); +int ratchet_identity_key_pair_deserialize(ratchet_identity_key_pair **key_pair, const uint8_t *data, size_t len, signal_context *global_context); ec_public_key *ratchet_identity_key_pair_get_public(const ratchet_identity_key_pair *key_pair); ec_private_key *ratchet_identity_key_pair_get_private(const ratchet_identity_key_pair *key_pair); -void ratchet_identity_key_pair_destroy(axolotl_type_base *type); +void ratchet_identity_key_pair_destroy(signal_type_base *type); -typedef struct symmetric_axolotl_parameters symmetric_axolotl_parameters; -typedef struct alice_axolotl_parameters alice_axolotl_parameters; -typedef struct bob_axolotl_parameters bob_axolotl_parameters; +typedef struct symmetric_signal_protocol_parameters symmetric_signal_protocol_parameters; +typedef struct alice_signal_protocol_parameters alice_signal_protocol_parameters; +typedef struct bob_signal_protocol_parameters bob_signal_protocol_parameters; -int symmetric_axolotl_parameters_create( - symmetric_axolotl_parameters **parameters, +int symmetric_signal_protocol_parameters_create( + symmetric_signal_protocol_parameters **parameters, ratchet_identity_key_pair *our_identity_key, ec_key_pair *our_base_key, ec_key_pair *our_ratchet_key, ec_public_key *their_base_key, ec_public_key *their_ratchet_key, ec_public_key *their_identity_key); -ratchet_identity_key_pair *symmetric_axolotl_parameters_get_our_identity_key(const symmetric_axolotl_parameters *parameters); -ec_key_pair *symmetric_axolotl_parameters_get_our_base_key(const symmetric_axolotl_parameters *parameters); -ec_key_pair *symmetric_axolotl_parameters_get_our_ratchet_key(const symmetric_axolotl_parameters *parameters); -ec_public_key *symmetric_axolotl_parameters_get_their_base_key(const symmetric_axolotl_parameters *parameters); -ec_public_key *symmetric_axolotl_parameters_get_their_ratchet_key(const symmetric_axolotl_parameters *parameters); -ec_public_key *symmetric_axolotl_parameters_get_their_identity_key(const symmetric_axolotl_parameters *parameters); -void symmetric_axolotl_parameters_destroy(axolotl_type_base *type); +ratchet_identity_key_pair *symmetric_signal_protocol_parameters_get_our_identity_key(const symmetric_signal_protocol_parameters *parameters); +ec_key_pair *symmetric_signal_protocol_parameters_get_our_base_key(const symmetric_signal_protocol_parameters *parameters); +ec_key_pair *symmetric_signal_protocol_parameters_get_our_ratchet_key(const symmetric_signal_protocol_parameters *parameters); +ec_public_key *symmetric_signal_protocol_parameters_get_their_base_key(const symmetric_signal_protocol_parameters *parameters); +ec_public_key *symmetric_signal_protocol_parameters_get_their_ratchet_key(const symmetric_signal_protocol_parameters *parameters); +ec_public_key *symmetric_signal_protocol_parameters_get_their_identity_key(const symmetric_signal_protocol_parameters *parameters); +void symmetric_signal_protocol_parameters_destroy(signal_type_base *type); -int alice_axolotl_parameters_create( - alice_axolotl_parameters **parameters, +int alice_signal_protocol_parameters_create( + alice_signal_protocol_parameters **parameters, ratchet_identity_key_pair *our_identity_key, ec_key_pair *our_base_key, ec_public_key *their_identity_key, ec_public_key *their_signed_pre_key, ec_public_key *their_one_time_pre_key, ec_public_key *their_ratchet_key); -void alice_axolotl_parameters_destroy(axolotl_type_base *type); +void alice_signal_protocol_parameters_destroy(signal_type_base *type); -int bob_axolotl_parameters_create( - bob_axolotl_parameters **parameters, +int bob_signal_protocol_parameters_create( + bob_signal_protocol_parameters **parameters, ratchet_identity_key_pair *our_identity_key, ec_key_pair *our_signed_pre_key, ec_key_pair *our_one_time_pre_key, ec_key_pair *our_ratchet_key, ec_public_key *their_identity_key, ec_public_key *their_base_key); -void bob_axolotl_parameters_destroy(axolotl_type_base *type); +void bob_signal_protocol_parameters_destroy(signal_type_base *type); -int ratcheting_session_symmetric_initialize(session_state *state, uint32_t version, symmetric_axolotl_parameters *parameters, axolotl_context *global_context); -int ratcheting_session_alice_initialize(session_state *state, uint32_t version, alice_axolotl_parameters *parameters, axolotl_context *global_context); -int ratcheting_session_bob_initialize(session_state *state, uint32_t version, bob_axolotl_parameters *parameters, axolotl_context *global_context); +int ratcheting_session_symmetric_initialize(session_state *state, symmetric_signal_protocol_parameters *parameters, signal_context *global_context); +int ratcheting_session_alice_initialize(session_state *state, alice_signal_protocol_parameters *parameters, signal_context *global_context); +int ratcheting_session_bob_initialize(session_state *state, bob_signal_protocol_parameters *parameters, signal_context *global_context); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/sender_key.c b/libs/libaxolotl/src/sender_key.c index 6647598fc9..31d7499499 100644 --- a/libs/libaxolotl/src/sender_key.c +++ b/libs/libaxolotl/src/sender_key.c @@ -4,32 +4,32 @@ #include <string.h> #include "hkdf.h" -#include "axolotl_internal.h" +#include "signal_protocol_internal.h" #define HASH_OUTPUT_SIZE 32 struct sender_message_key { - axolotl_type_base base; + signal_type_base base; uint32_t iteration; - axolotl_buffer *iv; - axolotl_buffer *cipher_key; - axolotl_buffer *seed; - axolotl_context *global_context; + signal_buffer *iv; + signal_buffer *cipher_key; + signal_buffer *seed; + signal_context *global_context; }; struct sender_chain_key { - axolotl_type_base base; + signal_type_base base; uint32_t iteration; - axolotl_buffer *chain_key; - axolotl_context *global_context; + signal_buffer *chain_key; + signal_context *global_context; }; -static int sender_chain_key_get_derivative(axolotl_buffer **derivative, uint8_t seed, axolotl_buffer *key, - axolotl_context *global_context); +static int sender_chain_key_get_derivative(signal_buffer **derivative, uint8_t seed, signal_buffer *key, + signal_context *global_context); int sender_message_key_create(sender_message_key **key, - uint32_t iteration, axolotl_buffer *seed, - axolotl_context *global_context) + uint32_t iteration, signal_buffer *seed, + signal_context *global_context) { sender_message_key *result = 0; int ret = 0; @@ -42,17 +42,17 @@ int sender_message_key_create(sender_message_key **key, assert(global_context); if(!seed) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } memset(salt, 0, sizeof(salt)); result = malloc(sizeof(sender_message_key)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - AXOLOTL_INIT(result, sender_message_key_destroy); + SIGNAL_INIT(result, sender_message_key_destroy); ret = hkdf_create(&kdf, 3, global_context); if(ret < 0) { @@ -60,44 +60,44 @@ int sender_message_key_create(sender_message_key **key, } ret_size = hkdf_derive_secrets(kdf, &derivative, - axolotl_buffer_data(seed), axolotl_buffer_len(seed), + signal_buffer_data(seed), signal_buffer_len(seed), salt, sizeof(salt), (uint8_t *)info_material, sizeof(info_material) - 1, 48); if(ret_size != 48) { - ret = (ret_size < 0) ? (int)ret_size : AX_ERR_UNKNOWN; - axolotl_log(global_context, AX_LOG_WARNING, "hkdf_derive_secrets failed"); + ret = (ret_size < 0) ? (int)ret_size : SG_ERR_UNKNOWN; + signal_log(global_context, SG_LOG_WARNING, "hkdf_derive_secrets failed"); goto complete; } result->iteration = iteration; - result->seed = axolotl_buffer_copy(seed); + result->seed = signal_buffer_copy(seed); if(!result->seed) { - ret = AX_ERR_NOMEM; + ret = SG_ERR_NOMEM; goto complete; } - result->iv = axolotl_buffer_create(derivative, 16); + result->iv = signal_buffer_create(derivative, 16); if(!result->iv) { - ret = AX_ERR_NOMEM; + ret = SG_ERR_NOMEM; goto complete; } - result->cipher_key = axolotl_buffer_create(derivative + 16, 32); + result->cipher_key = signal_buffer_create(derivative + 16, 32); if(!result->cipher_key) { - ret = AX_ERR_NOMEM; + ret = SG_ERR_NOMEM; goto complete; } result->global_context = global_context; complete: - AXOLOTL_UNREF(kdf); + SIGNAL_UNREF(kdf); if(derivative) { free(derivative); } if(ret < 0) { - AXOLOTL_UNREF(result); + SIGNAL_UNREF(result); } else { ret = 0; @@ -112,36 +112,36 @@ uint32_t sender_message_key_get_iteration(sender_message_key *key) return key->iteration; } -axolotl_buffer *sender_message_key_get_iv(sender_message_key *key) +signal_buffer *sender_message_key_get_iv(sender_message_key *key) { assert(key); return key->iv; } -axolotl_buffer *sender_message_key_get_cipher_key(sender_message_key *key) +signal_buffer *sender_message_key_get_cipher_key(sender_message_key *key) { assert(key); return key->cipher_key; } -axolotl_buffer *sender_message_key_get_seed(sender_message_key *key) +signal_buffer *sender_message_key_get_seed(sender_message_key *key) { assert(key); return key->seed; } -void sender_message_key_destroy(axolotl_type_base *type) +void sender_message_key_destroy(signal_type_base *type) { sender_message_key *key = (sender_message_key *)type; - axolotl_buffer_bzero_free(key->iv); - axolotl_buffer_bzero_free(key->cipher_key); - axolotl_buffer_bzero_free(key->seed); + signal_buffer_bzero_free(key->iv); + signal_buffer_bzero_free(key->cipher_key); + signal_buffer_bzero_free(key->seed); free(key); } int sender_chain_key_create(sender_chain_key **key, - uint32_t iteration, axolotl_buffer *chain_key, - axolotl_context *global_context) + uint32_t iteration, signal_buffer *chain_key, + signal_context *global_context) { sender_chain_key *result = 0; int ret = 0; @@ -149,21 +149,21 @@ int sender_chain_key_create(sender_chain_key **key, assert(global_context); if(!chain_key) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } result = malloc(sizeof(sender_chain_key)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - AXOLOTL_INIT(result, sender_chain_key_destroy); + SIGNAL_INIT(result, sender_chain_key_destroy); result->iteration = iteration; - result->chain_key = axolotl_buffer_copy(chain_key); + result->chain_key = signal_buffer_copy(chain_key); if(!result->chain_key) { - ret = AX_ERR_NOMEM; + ret = SG_ERR_NOMEM; goto complete; } @@ -171,7 +171,7 @@ int sender_chain_key_create(sender_chain_key **key, complete: if(ret < 0) { - AXOLOTL_UNREF(result); + SIGNAL_UNREF(result); } else { ret = 0; @@ -190,7 +190,7 @@ int sender_chain_key_create_message_key(sender_chain_key *key, sender_message_ke { static const uint8_t MESSAGE_KEY_SEED = 0x01; int ret = 0; - axolotl_buffer *derivative = 0; + signal_buffer *derivative = 0; sender_message_key *result = 0; assert(key); @@ -203,7 +203,7 @@ int sender_chain_key_create_message_key(sender_chain_key *key, sender_message_ke ret = sender_message_key_create(&result, key->iteration, derivative, key->global_context); complete: - axolotl_buffer_free(derivative); + signal_buffer_free(derivative); if(ret >= 0) { ret = 0; *message_key = result; @@ -215,7 +215,7 @@ int sender_chain_key_create_next(sender_chain_key *key, sender_chain_key **next_ { static const uint8_t CHAIN_KEY_SEED = 0x02; int ret = 0; - axolotl_buffer *derivative = 0; + signal_buffer *derivative = 0; sender_chain_key *result = 0; assert(key); @@ -228,7 +228,7 @@ int sender_chain_key_create_next(sender_chain_key *key, sender_chain_key **next_ ret = sender_chain_key_create(&result, key->iteration + 1, derivative, key->global_context); complete: - axolotl_buffer_free(derivative); + signal_buffer_free(derivative); if(ret >= 0) { ret = 0; *next_key = result; @@ -236,47 +236,47 @@ complete: return ret; } -axolotl_buffer *sender_chain_key_get_seed(sender_chain_key *key) +signal_buffer *sender_chain_key_get_seed(sender_chain_key *key) { assert(key); return key->chain_key; } -void sender_chain_key_destroy(axolotl_type_base *type) +void sender_chain_key_destroy(signal_type_base *type) { sender_chain_key *key = (sender_chain_key *)type; - axolotl_buffer_bzero_free(key->chain_key); + signal_buffer_bzero_free(key->chain_key); free(key); } -int sender_chain_key_get_derivative(axolotl_buffer **derivative, uint8_t seed, axolotl_buffer *key, - axolotl_context *global_context) +int sender_chain_key_get_derivative(signal_buffer **derivative, uint8_t seed, signal_buffer *key, + signal_context *global_context) { int result = 0; - axolotl_buffer *output_buffer = 0; + signal_buffer *output_buffer = 0; void *hmac_context = 0; - result = axolotl_hmac_sha256_init(global_context, &hmac_context, - axolotl_buffer_data(key), axolotl_buffer_len(key)); + result = signal_hmac_sha256_init(global_context, &hmac_context, + signal_buffer_data(key), signal_buffer_len(key)); if(result < 0) { goto complete; } - result = axolotl_hmac_sha256_update(global_context, hmac_context, &seed, sizeof(seed)); + result = signal_hmac_sha256_update(global_context, hmac_context, &seed, sizeof(seed)); if(result < 0) { goto complete; } - result = axolotl_hmac_sha256_final(global_context, hmac_context, &output_buffer); + result = signal_hmac_sha256_final(global_context, hmac_context, &output_buffer); if(result < 0) { goto complete; } complete: - axolotl_hmac_sha256_cleanup(global_context, hmac_context); + signal_hmac_sha256_cleanup(global_context, hmac_context); if(result < 0) { - axolotl_buffer_free(output_buffer); + signal_buffer_free(output_buffer); } else { *derivative = output_buffer; diff --git a/libs/libaxolotl/src/sender_key.h b/libs/libaxolotl/src/sender_key.h index 61bd7ef553..113bb5daa8 100644 --- a/libs/libaxolotl/src/sender_key.h +++ b/libs/libaxolotl/src/sender_key.h @@ -3,29 +3,29 @@ #include <stdint.h> #include <stddef.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { #endif int sender_message_key_create(sender_message_key **key, - uint32_t iteration, axolotl_buffer *seed, - axolotl_context *global_context); + uint32_t iteration, signal_buffer *seed, + signal_context *global_context); uint32_t sender_message_key_get_iteration(sender_message_key *key); -axolotl_buffer *sender_message_key_get_iv(sender_message_key *key); -axolotl_buffer *sender_message_key_get_cipher_key(sender_message_key *key); -axolotl_buffer *sender_message_key_get_seed(sender_message_key *key); -void sender_message_key_destroy(axolotl_type_base *type); +signal_buffer *sender_message_key_get_iv(sender_message_key *key); +signal_buffer *sender_message_key_get_cipher_key(sender_message_key *key); +signal_buffer *sender_message_key_get_seed(sender_message_key *key); +void sender_message_key_destroy(signal_type_base *type); int sender_chain_key_create(sender_chain_key **key, - uint32_t iteration, axolotl_buffer *chain_key, - axolotl_context *global_context); + uint32_t iteration, signal_buffer *chain_key, + signal_context *global_context); uint32_t sender_chain_key_get_iteration(sender_chain_key *key); int sender_chain_key_create_message_key(sender_chain_key *key, sender_message_key **message_key); int sender_chain_key_create_next(sender_chain_key *key, sender_chain_key **next_key); -axolotl_buffer *sender_chain_key_get_seed(sender_chain_key *key); -void sender_chain_key_destroy(axolotl_type_base *type); +signal_buffer *sender_chain_key_get_seed(sender_chain_key *key); +void sender_chain_key_destroy(signal_type_base *type); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/sender_key_record.c b/libs/libaxolotl/src/sender_key_record.c index 0d081f4278..9c7a2beeed 100644 --- a/libs/libaxolotl/src/sender_key_record.c +++ b/libs/libaxolotl/src/sender_key_record.c @@ -2,11 +2,11 @@ #include <string.h> -#include "axolotl_internal.h" #include "sender_key_state.h" #include "sender_key.h" #include "utlist.h" #include "LocalStorageProtocol.pb-c.h" +#include "signal_protocol_internal.h" #define MAX_STATES 5 @@ -17,20 +17,20 @@ typedef struct sender_key_state_node { struct sender_key_record { - axolotl_type_base base; + signal_type_base base; sender_key_state_node *sender_key_states_head; - axolotl_context *global_context; + signal_context *global_context; }; int sender_key_record_create(sender_key_record **record, - axolotl_context *global_context) + signal_context *global_context) { sender_key_record *result = malloc(sizeof(sender_key_record)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result, 0, sizeof(sender_key_record)); - AXOLOTL_INIT(result, sender_key_record_destroy); + SIGNAL_INIT(result, sender_key_record_destroy); result->global_context = global_context; @@ -38,29 +38,29 @@ int sender_key_record_create(sender_key_record **record, return 0; } -int sender_key_record_serialize(axolotl_buffer **buffer, sender_key_record *record) +int sender_key_record_serialize(signal_buffer **buffer, sender_key_record *record) { int result = 0; size_t result_size = 0; unsigned int i = 0; Textsecure__SenderKeyRecordStructure record_structure = TEXTSECURE__SENDER_KEY_RECORD_STRUCTURE__INIT; sender_key_state_node *cur_node = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; uint8_t *data; size_t len; if(record->sender_key_states_head) { - unsigned int count; + size_t count; DL_COUNT(record->sender_key_states_head, cur_node, count); if(count > SIZE_MAX / sizeof(Textsecure__SenderKeyStateStructure *)) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } record_structure.senderkeystates = malloc(sizeof(Textsecure__SenderKeyStateStructure *) * count); if(!record_structure.senderkeystates) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -68,7 +68,7 @@ int sender_key_record_serialize(axolotl_buffer **buffer, sender_key_record *reco DL_FOREACH(record->sender_key_states_head, cur_node) { record_structure.senderkeystates[i] = malloc(sizeof(Textsecure__SenderKeyStateStructure)); if(!record_structure.senderkeystates[i]) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; break; } textsecure__sender_key_state_structure__init(record_structure.senderkeystates[i]); @@ -87,17 +87,17 @@ int sender_key_record_serialize(axolotl_buffer **buffer, sender_key_record *reco len = textsecure__sender_key_record_structure__get_packed_size(&record_structure); - result_buf = axolotl_buffer_alloc(len); + result_buf = signal_buffer_alloc(len); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); result_size = textsecure__sender_key_record_structure__pack(&record_structure, data); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } @@ -118,7 +118,7 @@ complete: return result; } -int sender_key_record_deserialize(sender_key_record **record, const uint8_t *data, size_t len, axolotl_context *global_context) +int sender_key_record_deserialize(sender_key_record **record, const uint8_t *data, size_t len, signal_context *global_context) { int result = 0; sender_key_record *result_record = 0; @@ -126,7 +126,7 @@ int sender_key_record_deserialize(sender_key_record **record, const uint8_t *dat record_structure = textsecure__sender_key_record_structure__unpack(0, len, data); if(!record_structure) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } @@ -147,7 +147,7 @@ int sender_key_record_deserialize(sender_key_record **record, const uint8_t *dat state_node = malloc(sizeof(sender_key_state_node)); if(!state_node) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -162,7 +162,7 @@ complete: } if(result_record) { if(result < 0) { - AXOLOTL_UNREF(result_record); + SIGNAL_UNREF(result_record); } else { *record = result_record; @@ -171,10 +171,10 @@ complete: return result; } -int sender_key_record_copy(sender_key_record **record, sender_key_record *other_record, axolotl_context *global_context) +int sender_key_record_copy(sender_key_record **record, sender_key_record *other_record, signal_context *global_context) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; uint8_t *data; size_t len; @@ -186,8 +186,8 @@ int sender_key_record_copy(sender_key_record **record, sender_key_record *other_ goto complete; } - data = axolotl_buffer_data(buffer); - len = axolotl_buffer_len(buffer); + data = signal_buffer_data(buffer); + len = signal_buffer_len(buffer); result = sender_key_record_deserialize(record, data, len, global_context); if(result < 0) { @@ -196,7 +196,7 @@ int sender_key_record_copy(sender_key_record **record, sender_key_record *other_ complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } return result; } @@ -220,8 +220,8 @@ int sender_key_record_get_sender_key_state(sender_key_record *record, sender_key return 0; } else { - axolotl_log(record->global_context, AX_LOG_ERROR, "No key state in record!"); - return AX_ERR_INVALID_KEY_ID; + signal_log(record->global_context, SG_LOG_ERROR, "No key state in record!"); + return SG_ERR_INVALID_KEY_ID; } } @@ -237,12 +237,12 @@ int sender_key_record_get_sender_key_state_by_id(sender_key_record *record, send } } - axolotl_log(record->global_context, AX_LOG_ERROR, "No keys for: %d", key_id); - return AX_ERR_INVALID_KEY_ID; + signal_log(record->global_context, SG_LOG_ERROR, "No keys for: %d", key_id); + return SG_ERR_INVALID_KEY_ID; } static int sender_key_record_add_sender_key_state_impl(sender_key_record *record, - uint32_t id, uint32_t iteration, axolotl_buffer *chain_key, + uint32_t id, uint32_t iteration, signal_buffer *chain_key, ec_public_key *signature_public_key, ec_private_key *signature_private_key) { int result = 0; @@ -266,7 +266,7 @@ static int sender_key_record_add_sender_key_state_impl(sender_key_record *record state_node = malloc(sizeof(sender_key_state_node)); if(!state_node) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -278,22 +278,22 @@ static int sender_key_record_add_sender_key_state_impl(sender_key_record *record state_node = record->sender_key_states_head->prev; DL_DELETE(record->sender_key_states_head, state_node); if(state_node->state) { - AXOLOTL_UNREF(state_node->state); + SIGNAL_UNREF(state_node->state); } free(state_node); --count; } complete: - AXOLOTL_UNREF(chain_key_element); + SIGNAL_UNREF(chain_key_element); if(result < 0) { - AXOLOTL_UNREF(state); + SIGNAL_UNREF(state); } return result; } int sender_key_record_add_sender_key_state(sender_key_record *record, - uint32_t id, uint32_t iteration, axolotl_buffer *chain_key, ec_public_key *signature_key) + uint32_t id, uint32_t iteration, signal_buffer *chain_key, ec_public_key *signature_key) { int result = sender_key_record_add_sender_key_state_impl( record, id, iteration, chain_key, signature_key, 0); @@ -301,7 +301,7 @@ int sender_key_record_add_sender_key_state(sender_key_record *record, } int sender_key_record_set_sender_key_state(sender_key_record *record, - uint32_t id, uint32_t iteration, axolotl_buffer *chain_key, ec_key_pair *signature_key_pair) + uint32_t id, uint32_t iteration, signal_buffer *chain_key, ec_key_pair *signature_key_pair) { int result = 0; sender_key_state_node *cur_node; @@ -311,7 +311,7 @@ int sender_key_record_set_sender_key_state(sender_key_record *record, DL_FOREACH_SAFE(record->sender_key_states_head, cur_node, tmp_node) { DL_DELETE(record->sender_key_states_head, cur_node); if(cur_node->state) { - AXOLOTL_UNREF(cur_node->state); + SIGNAL_UNREF(cur_node->state); } free(cur_node); } @@ -324,7 +324,7 @@ int sender_key_record_set_sender_key_state(sender_key_record *record, return result; } -void sender_key_record_destroy(axolotl_type_base *type) +void sender_key_record_destroy(signal_type_base *type) { sender_key_record *record = (sender_key_record *)type; sender_key_state_node *cur_node; @@ -333,7 +333,7 @@ void sender_key_record_destroy(axolotl_type_base *type) DL_FOREACH_SAFE(record->sender_key_states_head, cur_node, tmp_node) { DL_DELETE(record->sender_key_states_head, cur_node); if(cur_node->state) { - AXOLOTL_UNREF(cur_node->state); + SIGNAL_UNREF(cur_node->state); } free(cur_node); } diff --git a/libs/libaxolotl/src/sender_key_record.h b/libs/libaxolotl/src/sender_key_record.h index a50d6451ac..4cc4f92715 100644 --- a/libs/libaxolotl/src/sender_key_record.h +++ b/libs/libaxolotl/src/sender_key_record.h @@ -1,27 +1,27 @@ #ifndef SENDER_KEY_RECORD_H #define SENDER_KEY_RECORD_H -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { #endif int sender_key_record_create(sender_key_record **record, - axolotl_context *global_context); -int sender_key_record_serialize(axolotl_buffer **buffer, sender_key_record *record); -int sender_key_record_deserialize(sender_key_record **record, const uint8_t *data, size_t len, axolotl_context *global_context); -int sender_key_record_copy(sender_key_record **record, sender_key_record *other_state, axolotl_context *global_context); + signal_context *global_context); +int sender_key_record_serialize(signal_buffer **buffer, sender_key_record *record); +int sender_key_record_deserialize(sender_key_record **record, const uint8_t *data, size_t len, signal_context *global_context); +int sender_key_record_copy(sender_key_record **record, sender_key_record *other_state, signal_context *global_context); int sender_key_record_is_empty(sender_key_record *record); int sender_key_record_get_sender_key_state(sender_key_record *record, sender_key_state **state); int sender_key_record_get_sender_key_state_by_id(sender_key_record *record, sender_key_state **state, uint32_t key_id); int sender_key_record_add_sender_key_state(sender_key_record *record, - uint32_t id, uint32_t iteration, axolotl_buffer *chain_key, ec_public_key *signature_key); + uint32_t id, uint32_t iteration, signal_buffer *chain_key, ec_public_key *signature_key); int sender_key_record_set_sender_key_state(sender_key_record *record, - uint32_t id, uint32_t iteration, axolotl_buffer *chain_key, ec_key_pair *signature_key_pair); + uint32_t id, uint32_t iteration, signal_buffer *chain_key, ec_key_pair *signature_key_pair); -void sender_key_record_destroy(axolotl_type_base *type); +void sender_key_record_destroy(signal_type_base *type); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/sender_key_state.c b/libs/libaxolotl/src/sender_key_state.c index fd65965fda..0b19cb7412 100644 --- a/libs/libaxolotl/src/sender_key_state.c +++ b/libs/libaxolotl/src/sender_key_state.c @@ -5,9 +5,9 @@ #include <assert.h> #include "sender_key.h" -#include "axolotl_internal.h" #include "utlist.h" #include "LocalStorageProtocol.pb-c.h" +#include "signal_protocol_internal.h" #define MAX_MESSAGE_KEYS 2000 @@ -18,7 +18,7 @@ typedef struct sender_message_key_node { struct sender_key_state { - axolotl_type_base base; + signal_type_base base; uint32_t key_id; sender_chain_key *chain_key; @@ -26,37 +26,37 @@ struct sender_key_state ec_private_key *signature_private_key; sender_message_key_node *message_keys_head; - axolotl_context *global_context; + signal_context *global_context; }; int sender_key_state_create(sender_key_state **state, uint32_t id, sender_chain_key *chain_key, ec_public_key *signature_public_key, ec_private_key *signature_private_key, - axolotl_context *global_context) + signal_context *global_context) { sender_key_state *result = 0; if(!chain_key || !signature_public_key) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } result = malloc(sizeof(sender_key_state)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result, 0, sizeof(sender_key_state)); - AXOLOTL_INIT(result, sender_key_state_destroy); + SIGNAL_INIT(result, sender_key_state_destroy); result->key_id = id; - AXOLOTL_REF(chain_key); + SIGNAL_REF(chain_key); result->chain_key = chain_key; - AXOLOTL_REF(signature_public_key); + SIGNAL_REF(signature_public_key); result->signature_public_key = signature_public_key; if(signature_private_key) { - AXOLOTL_REF(signature_private_key); + SIGNAL_REF(signature_private_key); result->signature_private_key = signature_private_key; } @@ -66,18 +66,18 @@ int sender_key_state_create(sender_key_state **state, return 0; } -int sender_key_state_serialize(axolotl_buffer **buffer, sender_key_state *state) +int sender_key_state_serialize(signal_buffer **buffer, sender_key_state *state) { int result = 0; size_t result_size = 0; uint8_t *data; size_t len; Textsecure__SenderKeyStateStructure *state_structure = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; state_structure = malloc(sizeof(Textsecure__SenderKeyStateStructure)); if(!state_structure) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } textsecure__sender_key_state_structure__init(state_structure); @@ -89,17 +89,17 @@ int sender_key_state_serialize(axolotl_buffer **buffer, sender_key_state *state) len = textsecure__sender_key_state_structure__get_packed_size(state_structure); - result_buf = axolotl_buffer_alloc(len); + result_buf = signal_buffer_alloc(len); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); result_size = textsecure__sender_key_state_structure__pack(state_structure, data); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } @@ -114,7 +114,7 @@ complete: return result; } -int sender_key_state_deserialize(sender_key_state **state, const uint8_t *data, size_t len, axolotl_context *global_context) +int sender_key_state_deserialize(sender_key_state **state, const uint8_t *data, size_t len, signal_context *global_context) { int result = 0; Textsecure__SenderKeyStateStructure *state_structure = 0; @@ -122,7 +122,7 @@ int sender_key_state_deserialize(sender_key_state **state, const uint8_t *data, state_structure = textsecure__sender_key_state_structure__unpack(0, len, data); if(!state_structure) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } @@ -137,7 +137,7 @@ complete: } if(result_state) { if(result < 0) { - AXOLOTL_UNREF(result_state); + SIGNAL_UNREF(result_state); } else { *state = result_state; @@ -154,7 +154,7 @@ int sender_key_state_serialize_prepare(sender_key_state *state, Textsecure__Send Textsecure__SenderKeyStateStructure__SenderChainKey *chain_key_structure = 0; Textsecure__SenderKeyStateStructure__SenderSigningKey *signing_key_structure = 0; sender_message_key_node *cur_node = 0; - axolotl_buffer *chain_key_seed = 0; + signal_buffer *chain_key_seed = 0; assert(state); assert(state_structure); @@ -166,7 +166,7 @@ int sender_key_state_serialize_prepare(sender_key_state *state, Textsecure__Send /* Sender chain key */ chain_key_structure = malloc(sizeof(Textsecure__SenderKeyStateStructure__SenderChainKey)); if(!chain_key_structure) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } textsecure__sender_key_state_structure__sender_chain_key__init(chain_key_structure); @@ -176,14 +176,14 @@ int sender_key_state_serialize_prepare(sender_key_state *state, Textsecure__Send chain_key_structure->has_iteration = 1; chain_key_seed = sender_chain_key_get_seed(state->chain_key); - chain_key_structure->seed.data = axolotl_buffer_data(chain_key_seed); - chain_key_structure->seed.len = axolotl_buffer_len(chain_key_seed); + chain_key_structure->seed.data = signal_buffer_data(chain_key_seed); + chain_key_structure->seed.len = signal_buffer_len(chain_key_seed); chain_key_structure->has_seed = 1; /* Sender signing key */ signing_key_structure = malloc(sizeof(Textsecure__SenderKeyStateStructure__SenderSigningKey)); if(!signing_key_structure) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } textsecure__sender_key_state_structure__sender_signing_key__init(signing_key_structure); @@ -207,26 +207,26 @@ int sender_key_state_serialize_prepare(sender_key_state *state, Textsecure__Send /* Sender message keys */ if(state->message_keys_head) { - unsigned int count; + size_t count; DL_COUNT(state->message_keys_head, cur_node, count); if(count > SIZE_MAX / sizeof(Textsecure__SenderKeyStateStructure__SenderMessageKey *)) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } state_structure->sendermessagekeys = malloc(sizeof(Textsecure__SenderKeyStateStructure__SenderMessageKey *) * count); if(!state_structure->sendermessagekeys) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } i = 0; DL_FOREACH(state->message_keys_head, cur_node) { - axolotl_buffer *seed = 0; + signal_buffer *seed = 0; state_structure->sendermessagekeys[i] = malloc(sizeof(Textsecure__SenderKeyStateStructure__SenderMessageKey)); if(!state_structure->sendermessagekeys[i]) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; break; } textsecure__sender_key_state_structure__sender_message_key__init(state_structure->sendermessagekeys[i]); @@ -235,8 +235,8 @@ int sender_key_state_serialize_prepare(sender_key_state *state, Textsecure__Send state_structure->sendermessagekeys[i]->has_iteration = 1; seed = sender_message_key_get_seed(cur_node->key); - state_structure->sendermessagekeys[i]->seed.data = axolotl_buffer_data(seed); - state_structure->sendermessagekeys[i]->seed.len = axolotl_buffer_len(seed); + state_structure->sendermessagekeys[i]->seed.data = signal_buffer_data(seed); + state_structure->sendermessagekeys[i]->seed.len = signal_buffer_len(seed); state_structure->sendermessagekeys[i]->has_seed = 1; if(result < 0) { @@ -281,7 +281,7 @@ void sender_key_state_serialize_prepare_free(Textsecure__SenderKeyStateStructure free(state_structure); } -int sender_key_state_deserialize_protobuf(sender_key_state **state, Textsecure__SenderKeyStateStructure *state_structure, axolotl_context *global_context) +int sender_key_state_deserialize_protobuf(sender_key_state **state, Textsecure__SenderKeyStateStructure *state_structure, signal_context *global_context) { int result = 0; sender_key_state *result_state = 0; @@ -292,11 +292,11 @@ int sender_key_state_deserialize_protobuf(sender_key_state **state, Textsecure__ if(state_structure->senderchainkey && state_structure->senderchainkey->has_iteration && state_structure->senderchainkey->has_seed) { - axolotl_buffer *seed_buffer = axolotl_buffer_create( + signal_buffer *seed_buffer = signal_buffer_create( state_structure->senderchainkey->seed.data, state_structure->senderchainkey->seed.len); if(!seed_buffer) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -304,7 +304,7 @@ int sender_key_state_deserialize_protobuf(sender_key_state **state, Textsecure__ state_structure->senderchainkey->iteration, seed_buffer, global_context); - axolotl_buffer_free(seed_buffer); + signal_buffer_free(seed_buffer); if(result < 0) { goto complete; } @@ -337,10 +337,13 @@ int sender_key_state_deserialize_protobuf(sender_key_state **state, Textsecure__ state_structure->senderkeyid, chain_key, signature_public_key, signature_private_key, global_context); + if(result < 0) { + goto complete; + } if(state_structure->n_sendermessagekeys > 0) { for(i = 0; i < state_structure->n_sendermessagekeys; i++) { - axolotl_buffer *seed_buffer; + signal_buffer *seed_buffer; sender_message_key *message_key; Textsecure__SenderKeyStateStructure__SenderMessageKey *message_key_structure = state_structure->sendermessagekeys[i]; @@ -349,18 +352,18 @@ int sender_key_state_deserialize_protobuf(sender_key_state **state, Textsecure__ continue; } - seed_buffer = axolotl_buffer_create( + seed_buffer = signal_buffer_create( message_key_structure->seed.data, message_key_structure->seed.len); if(!seed_buffer) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } result = sender_message_key_create(&message_key, message_key_structure->iteration, seed_buffer, global_context); - axolotl_buffer_free(seed_buffer); + signal_buffer_free(seed_buffer); if(result < 0) { goto complete; } @@ -369,36 +372,39 @@ int sender_key_state_deserialize_protobuf(sender_key_state **state, Textsecure__ if(result < 0) { goto complete; } - AXOLOTL_UNREF(message_key); + SIGNAL_UNREF(message_key); } } } + else { + result = SG_ERR_INVALID_PROTO_BUF; + } complete: if(chain_key) { - AXOLOTL_UNREF(chain_key); + SIGNAL_UNREF(chain_key); } if(signature_public_key) { - AXOLOTL_UNREF(signature_public_key); + SIGNAL_UNREF(signature_public_key); } if(signature_private_key) { - AXOLOTL_UNREF(signature_private_key); + SIGNAL_UNREF(signature_private_key); } if(result >= 0) { *state = result_state; } else { if(result_state) { - AXOLOTL_UNREF(result_state); + SIGNAL_UNREF(result_state); } } return result; } -int sender_key_state_copy(sender_key_state **state, sender_key_state *other_state, axolotl_context *global_context) +int sender_key_state_copy(sender_key_state **state, sender_key_state *other_state, signal_context *global_context) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; uint8_t *data; size_t len; @@ -410,8 +416,8 @@ int sender_key_state_copy(sender_key_state **state, sender_key_state *other_stat goto complete; } - data = axolotl_buffer_data(buffer); - len = axolotl_buffer_len(buffer); + data = signal_buffer_data(buffer); + len = signal_buffer_len(buffer); result = sender_key_state_deserialize(state, data, len, global_context); if(result < 0) { @@ -420,7 +426,7 @@ int sender_key_state_copy(sender_key_state **state, sender_key_state *other_stat complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } return result; } @@ -443,9 +449,9 @@ void sender_key_state_set_chain_key(sender_key_state *state, sender_chain_key *c assert(chain_key); if(state->chain_key) { - AXOLOTL_UNREF(state->chain_key); + SIGNAL_UNREF(state->chain_key); } - AXOLOTL_REF(chain_key); + SIGNAL_REF(chain_key); state->chain_key = chain_key; } @@ -485,11 +491,11 @@ int sender_key_state_add_sender_message_key(sender_key_state *state, sender_mess node = malloc(sizeof(sender_message_key_node)); if(!node) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - AXOLOTL_REF(message_key); + SIGNAL_REF(message_key); node->key = message_key; DL_APPEND(state->message_keys_head, node); @@ -498,7 +504,7 @@ int sender_key_state_add_sender_message_key(sender_key_state *state, sender_mess node = state->message_keys_head; DL_DELETE(state->message_keys_head, node); if(node->key) { - AXOLOTL_UNREF(node->key); + SIGNAL_UNREF(node->key); } free(node); --count; @@ -527,20 +533,20 @@ sender_message_key *sender_key_state_remove_sender_message_key(sender_key_state return result; } -void sender_key_state_destroy(axolotl_type_base *type) +void sender_key_state_destroy(signal_type_base *type) { sender_key_state *state = (sender_key_state *)type; sender_message_key_node *cur_node; sender_message_key_node *tmp_node; - AXOLOTL_UNREF(state->chain_key); - AXOLOTL_UNREF(state->signature_public_key); - AXOLOTL_UNREF(state->signature_private_key); + SIGNAL_UNREF(state->chain_key); + SIGNAL_UNREF(state->signature_public_key); + SIGNAL_UNREF(state->signature_private_key); DL_FOREACH_SAFE(state->message_keys_head, cur_node, tmp_node) { DL_DELETE(state->message_keys_head, cur_node); if(cur_node->key) { - AXOLOTL_UNREF(cur_node->key); + SIGNAL_UNREF(cur_node->key); } free(cur_node); } diff --git a/libs/libaxolotl/src/sender_key_state.h b/libs/libaxolotl/src/sender_key_state.h index 117afa43be..968c7fb753 100644 --- a/libs/libaxolotl/src/sender_key_state.h +++ b/libs/libaxolotl/src/sender_key_state.h @@ -2,7 +2,7 @@ #define SENDER_KEY_STATE_H #include <stdint.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { @@ -11,10 +11,10 @@ extern "C" { int sender_key_state_create(sender_key_state **state, uint32_t id, sender_chain_key *chain_key, ec_public_key *signature_public_key, ec_private_key *signature_private_key, - axolotl_context *global_context); -int sender_key_state_serialize(axolotl_buffer **buffer, sender_key_state *state); -int sender_key_state_deserialize(sender_key_state **state, const uint8_t *data, size_t len, axolotl_context *global_context); -int sender_key_state_copy(sender_key_state **state, sender_key_state *other_state, axolotl_context *global_context); + signal_context *global_context); +int sender_key_state_serialize(signal_buffer **buffer, sender_key_state *state); +int sender_key_state_deserialize(sender_key_state **state, const uint8_t *data, size_t len, signal_context *global_context); +int sender_key_state_copy(sender_key_state **state, sender_key_state *other_state, signal_context *global_context); uint32_t sender_key_state_get_key_id(sender_key_state *state); sender_chain_key *sender_key_state_get_chain_key(sender_key_state *state); @@ -25,7 +25,7 @@ int sender_key_state_has_sender_message_key(sender_key_state *state, uint32_t it int sender_key_state_add_sender_message_key(sender_key_state *state, sender_message_key *message_key); sender_message_key *sender_key_state_remove_sender_message_key(sender_key_state *state, uint32_t iteration); -void sender_key_state_destroy(axolotl_type_base *type); +void sender_key_state_destroy(signal_type_base *type); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/session_builder.c b/libs/libaxolotl/src/session_builder.c index b962c21b5f..2bfd62015f 100644 --- a/libs/libaxolotl/src/session_builder.c +++ b/libs/libaxolotl/src/session_builder.c @@ -1,36 +1,29 @@ #include "session_builder.h" +#include "session_builder_internal.h" #include <assert.h> #include <string.h> -#include "axolotl_internal.h" #include "session_pre_key.h" #include "session_record.h" #include "session_state.h" #include "ratchet.h" #include "protocol.h" #include "key_helper.h" - -#define MIN(a,b) (((a)<(b))?(a):(b)) +#include "signal_protocol_internal.h" struct session_builder { - axolotl_store_context *store; - const axolotl_address *remote_address; - axolotl_context *global_context; + signal_protocol_store_context *store; + const signal_protocol_address *remote_address; + signal_context *global_context; }; -static int session_builder_process_pre_key_whisper_message_v2(session_builder *builder, - session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id); -static int session_builder_process_pre_key_whisper_message_v3(session_builder *builder, - session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id); -static int session_builder_process_initiate(session_builder *builder, - key_exchange_message *message, key_exchange_message **response_message); -static int session_builder_process_response(session_builder *builder, - key_exchange_message *message); +static int session_builder_process_pre_key_signal_message_v3(session_builder *builder, + session_record *record, pre_key_signal_message *message, uint32_t *unsigned_pre_key_id); int session_builder_create(session_builder **builder, - axolotl_store_context *store, const axolotl_address *remote_address, - axolotl_context *global_context) + signal_protocol_store_context *store, const signal_protocol_address *remote_address, + signal_context *global_context) { session_builder *result = 0; @@ -39,7 +32,7 @@ int session_builder_create(session_builder **builder, result = malloc(sizeof(session_builder)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result, 0, sizeof(session_builder)); @@ -51,43 +44,33 @@ int session_builder_create(session_builder **builder, return 0; } -int session_builder_process_pre_key_whisper_message(session_builder *builder, - session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id) +int session_builder_process_pre_key_signal_message(session_builder *builder, + session_record *record, pre_key_signal_message *message, uint32_t *unsigned_pre_key_id) { int result = 0; int has_unsigned_pre_key_id_result = 0; uint32_t unsigned_pre_key_id_result = 0; - int message_version = pre_key_whisper_message_get_message_version(message); - ec_public_key *their_identity_key = pre_key_whisper_message_get_identity_key(message); + ec_public_key *their_identity_key = pre_key_signal_message_get_identity_key(message); - result = axolotl_identity_is_trusted_identity(builder->store, - builder->remote_address->name, builder->remote_address->name_len, + result = signal_protocol_identity_is_trusted_identity(builder->store, + builder->remote_address, their_identity_key); if(result < 0) { goto complete; } if(result == 0) { - result = AX_ERR_UNTRUSTED_IDENTITY; + result = SG_ERR_UNTRUSTED_IDENTITY; goto complete; } - if(message_version == 2) { - result = session_builder_process_pre_key_whisper_message_v2(builder, record, message, &unsigned_pre_key_id_result); - } - else if(message_version == 3) { - result = session_builder_process_pre_key_whisper_message_v3(builder, record, message, &unsigned_pre_key_id_result); - } - else { - axolotl_log(builder->global_context, AX_LOG_WARNING, "Unknown version: %d", message_version); - result = AX_ERR_INVALID_VERSION; - } + result = session_builder_process_pre_key_signal_message_v3(builder, record, message, &unsigned_pre_key_id_result); if(result < 0) { goto complete; } has_unsigned_pre_key_id_result = result; - result = axolotl_identity_save_identity(builder->store, - builder->remote_address->name, builder->remote_address->name_len, + result = signal_protocol_identity_save_identity(builder->store, + builder->remote_address, their_identity_key); if(result < 0) { goto complete; @@ -102,195 +85,92 @@ complete: return result; } -static int session_builder_process_pre_key_whisper_message_v2(session_builder *builder, - session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id) -{ - int result = 0; - uint32_t unsigned_pre_key_id_result = 0; - session_pre_key *our_pre_key = 0; - ratchet_identity_key_pair *our_identity_key = 0; - bob_axolotl_parameters *parameters = 0; - uint32_t pre_key_id = 0; - int contains_session = 0; - session_state *state = 0; - int contains_key = 0; - uint32_t local_registration_id = 0; - - if(!pre_key_whisper_message_has_pre_key_id(message)) { - axolotl_log(builder->global_context, AX_LOG_WARNING, "V2 message requires one time pre key ID!"); - result = AX_ERR_INVALID_KEY_ID; - goto complete; - } - - pre_key_id = pre_key_whisper_message_get_pre_key_id(message); - - contains_key = axolotl_pre_key_contains_key(builder->store, pre_key_id); - if(contains_key < 0) { - result = contains_key; - goto complete; - } - - contains_session = axolotl_session_contains_session(builder->store, builder->remote_address); - if(contains_session < 0) { - result = contains_session; - goto complete; - } - - if(!contains_key && contains_session) { - axolotl_log(builder->global_context, AX_LOG_INFO, "We've already processed the prekey part of this V2 session, letting bundled message fall through..."); - result = 0; - goto complete; - } - - result = axolotl_pre_key_load_key(builder->store, &our_pre_key, pre_key_id); - if(result < 0) { - goto complete; - } - - result = axolotl_identity_get_key_pair(builder->store, &our_identity_key); - if(result < 0) { - goto complete; - } - - result = bob_axolotl_parameters_create( - ¶meters, - our_identity_key, - session_pre_key_get_key_pair(our_pre_key), - 0, - session_pre_key_get_key_pair(our_pre_key), - pre_key_whisper_message_get_identity_key(message), - pre_key_whisper_message_get_base_key(message)); - if(result < 0) { - goto complete; - } - - if(!session_record_is_fresh(record)) { - session_record_archive_current_state(record); - } - - state = session_record_get_state(record); - - result = ratcheting_session_bob_initialize( - state, - pre_key_whisper_message_get_message_version(message), - parameters, builder->global_context); - if(result < 0) { - goto complete; - } - - result = axolotl_identity_get_local_registration_id(builder->store, &local_registration_id); - if(result < 0) { - goto complete; - } - - session_state_set_local_registration_id(state, local_registration_id); - session_state_set_remote_registration_id(state, - pre_key_whisper_message_get_registration_id(message)); - session_state_set_alice_base_key(state, - pre_key_whisper_message_get_base_key(message));; - - if(pre_key_whisper_message_get_pre_key_id(message) != PRE_KEY_MEDIUM_MAX_VALUE) { - unsigned_pre_key_id_result = pre_key_whisper_message_get_pre_key_id(message); - result = 1; - } - else { - result = 0; - } - -complete: - AXOLOTL_UNREF(parameters); - AXOLOTL_UNREF(our_identity_key); - AXOLOTL_UNREF(our_pre_key); - if(result >= 0) { - *unsigned_pre_key_id = unsigned_pre_key_id_result; - } - return result; -} - -static int session_builder_process_pre_key_whisper_message_v3(session_builder *builder, - session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id) +static int session_builder_process_pre_key_signal_message_v3(session_builder *builder, + session_record *record, pre_key_signal_message *message, uint32_t *unsigned_pre_key_id) { int result = 0; uint32_t unsigned_pre_key_id_result = 0; session_signed_pre_key *our_signed_pre_key = 0; ratchet_identity_key_pair *our_identity_key = 0; - bob_axolotl_parameters *parameters = 0; + bob_signal_protocol_parameters *parameters = 0; session_pre_key *session_our_one_time_pre_key = 0; ec_key_pair *our_one_time_pre_key = 0; session_state *state = 0; uint32_t local_registration_id = 0; int has_session_state = session_record_has_session_state(record, - pre_key_whisper_message_get_message_version(message), - pre_key_whisper_message_get_base_key(message)); + pre_key_signal_message_get_message_version(message), + pre_key_signal_message_get_base_key(message)); if(has_session_state) { - axolotl_log(builder->global_context, AX_LOG_INFO, "We've already setup a session for this V3 message, letting bundled message fall through..."); + signal_log(builder->global_context, SG_LOG_INFO, "We've already setup a session for this V3 message, letting bundled message fall through..."); result = 0; goto complete; } - result = axolotl_signed_pre_key_load_key(builder->store, + result = signal_protocol_signed_pre_key_load_key(builder->store, &our_signed_pre_key, - pre_key_whisper_message_get_signed_pre_key_id(message)); + pre_key_signal_message_get_signed_pre_key_id(message)); if(result < 0) { goto complete; } - result = axolotl_identity_get_key_pair(builder->store, &our_identity_key); + result = signal_protocol_identity_get_key_pair(builder->store, &our_identity_key); if(result < 0) { goto complete; } - if(pre_key_whisper_message_has_pre_key_id(message)) { - result = axolotl_pre_key_load_key(builder->store, + if(pre_key_signal_message_has_pre_key_id(message)) { + result = signal_protocol_pre_key_load_key(builder->store, &session_our_one_time_pre_key, - pre_key_whisper_message_get_pre_key_id(message)); + pre_key_signal_message_get_pre_key_id(message)); if(result < 0) { goto complete; } our_one_time_pre_key = session_pre_key_get_key_pair(session_our_one_time_pre_key); } - result = bob_axolotl_parameters_create( + result = bob_signal_protocol_parameters_create( ¶meters, our_identity_key, session_signed_pre_key_get_key_pair(our_signed_pre_key), our_one_time_pre_key, session_signed_pre_key_get_key_pair(our_signed_pre_key), - pre_key_whisper_message_get_identity_key(message), - pre_key_whisper_message_get_base_key(message)); + pre_key_signal_message_get_identity_key(message), + pre_key_signal_message_get_base_key(message)); if(result < 0) { goto complete; } if(!session_record_is_fresh(record)) { - session_record_archive_current_state(record); + result = session_record_archive_current_state(record); + if(result < 0) { + goto complete; + } } state = session_record_get_state(record); result = ratcheting_session_bob_initialize( - state, - pre_key_whisper_message_get_message_version(message), - parameters, builder->global_context); + state, parameters, + builder->global_context); if(result < 0) { goto complete; } - result = axolotl_identity_get_local_registration_id(builder->store, &local_registration_id); + result = signal_protocol_identity_get_local_registration_id(builder->store, &local_registration_id); if(result < 0) { goto complete; } session_state_set_local_registration_id(state, local_registration_id); session_state_set_remote_registration_id(state, - pre_key_whisper_message_get_registration_id(message)); + pre_key_signal_message_get_registration_id(message)); session_state_set_alice_base_key(state, - pre_key_whisper_message_get_base_key(message));; + pre_key_signal_message_get_base_key(message));; - if(pre_key_whisper_message_has_pre_key_id(message) && - pre_key_whisper_message_get_pre_key_id(message) != PRE_KEY_MEDIUM_MAX_VALUE) { - unsigned_pre_key_id_result = pre_key_whisper_message_get_pre_key_id(message); + if(pre_key_signal_message_has_pre_key_id(message) && + pre_key_signal_message_get_pre_key_id(message) != PRE_KEY_MEDIUM_MAX_VALUE) { + unsigned_pre_key_id_result = pre_key_signal_message_get_pre_key_id(message); result = 1; } else { @@ -298,10 +178,10 @@ static int session_builder_process_pre_key_whisper_message_v3(session_builder *b } complete: - AXOLOTL_UNREF(parameters); - AXOLOTL_UNREF(our_identity_key); - AXOLOTL_UNREF(our_signed_pre_key); - AXOLOTL_UNREF(session_our_one_time_pre_key); + SIGNAL_UNREF(parameters); + SIGNAL_UNREF(our_identity_key); + SIGNAL_UNREF(our_signed_pre_key); + SIGNAL_UNREF(session_our_one_time_pre_key); if(result >= 0) { *unsigned_pre_key_id = unsigned_pre_key_id_result; } @@ -314,10 +194,9 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre session_record *record = 0; ec_key_pair *our_base_key = 0; ratchet_identity_key_pair *our_identity_key = 0; - alice_axolotl_parameters *parameters = 0; + alice_signal_protocol_parameters *parameters = 0; ec_public_key *signed_pre_key = 0; ec_public_key *pre_key = 0; - int supports_v3 = 0; ec_public_key *their_identity_key = 0; ec_public_key *their_signed_pre_key = 0; ec_public_key *their_one_time_pre_key = 0; @@ -329,16 +208,16 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre assert(builder); assert(builder->store); assert(bundle); - axolotl_lock(builder->global_context); + signal_lock(builder->global_context); - result = axolotl_identity_is_trusted_identity(builder->store, - builder->remote_address->name, builder->remote_address->name_len, + result = signal_protocol_identity_is_trusted_identity(builder->store, + builder->remote_address, session_pre_key_bundle_get_identity_key(bundle)); if(result < 0) { goto complete; } if(result == 0) { - result = AX_ERR_UNTRUSTED_IDENTITY; + result = SG_ERR_UNTRUSTED_IDENTITY; goto complete; } @@ -347,40 +226,38 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre if(signed_pre_key) { ec_public_key *identity_key = session_pre_key_bundle_get_identity_key(bundle); - axolotl_buffer *signature = session_pre_key_bundle_get_signed_pre_key_signature(bundle); + signal_buffer *signature = session_pre_key_bundle_get_signed_pre_key_signature(bundle); - axolotl_buffer *serialized_signed_pre_key = 0; + signal_buffer *serialized_signed_pre_key = 0; result = ec_public_key_serialize(&serialized_signed_pre_key, signed_pre_key); if(result < 0) { goto complete; } result = curve_verify_signature(identity_key, - axolotl_buffer_data(serialized_signed_pre_key), - axolotl_buffer_len(serialized_signed_pre_key), - axolotl_buffer_data(signature), - axolotl_buffer_len(signature)); + signal_buffer_data(serialized_signed_pre_key), + signal_buffer_len(serialized_signed_pre_key), + signal_buffer_data(signature), + signal_buffer_len(signature)); - axolotl_buffer_free(serialized_signed_pre_key); + signal_buffer_free(serialized_signed_pre_key); if(result == 0) { - axolotl_log(builder->global_context, AX_LOG_WARNING, "invalid signature on device key!"); - result = AX_ERR_INVALID_KEY; + signal_log(builder->global_context, SG_LOG_WARNING, "invalid signature on device key!"); + result = SG_ERR_INVALID_KEY; } if(result < 0) { goto complete; } } - if(!signed_pre_key && !pre_key) { - result = AX_ERR_INVALID_KEY; - axolotl_log(builder->global_context, AX_LOG_WARNING, "both signed and unsigned pre keys are absent!"); + if(!signed_pre_key) { + result = SG_ERR_INVALID_KEY; + signal_log(builder->global_context, SG_LOG_WARNING, "no signed pre key!"); goto complete; } - supports_v3 = (signed_pre_key != 0); - - result = axolotl_session_load_session(builder->store, &record, builder->remote_address); + result = signal_protocol_session_load_session(builder->store, &record, builder->remote_address); if(result < 0) { goto complete; } @@ -391,8 +268,7 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre } their_identity_key = session_pre_key_bundle_get_identity_key(bundle); - their_signed_pre_key = supports_v3 ? signed_pre_key : pre_key; - + their_signed_pre_key = signed_pre_key; their_one_time_pre_key = pre_key; if(their_one_time_pre_key) { @@ -400,31 +276,33 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre their_one_time_pre_key_id = session_pre_key_bundle_get_pre_key_id(bundle); } - result = axolotl_identity_get_key_pair(builder->store, &our_identity_key); + result = signal_protocol_identity_get_key_pair(builder->store, &our_identity_key); if(result < 0) { goto complete; } - result = alice_axolotl_parameters_create(¶meters, + result = alice_signal_protocol_parameters_create(¶meters, our_identity_key, our_base_key, their_identity_key, their_signed_pre_key, - supports_v3 ? their_one_time_pre_key : 0, + their_one_time_pre_key, their_signed_pre_key); if(result < 0) { goto complete; } if(!session_record_is_fresh(record)) { - session_record_archive_current_state(record); + result = session_record_archive_current_state(record); + if(result < 0) { + goto complete; + } } state = session_record_get_state(record); result = ratcheting_session_alice_initialize( - state, - supports_v3 ? 3 : 2, parameters, + state, parameters, builder->global_context); if(result < 0) { goto complete; @@ -435,7 +313,7 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre session_pre_key_bundle_get_signed_pre_key_id(bundle), ec_key_pair_get_public(our_base_key)); - result = axolotl_identity_get_local_registration_id(builder->store, &local_registration_id); + result = signal_protocol_identity_get_local_registration_id(builder->store, &local_registration_id); if(result < 0) { goto complete; } @@ -445,417 +323,24 @@ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre session_pre_key_bundle_get_registration_id(bundle)); session_state_set_alice_base_key(state, ec_key_pair_get_public(our_base_key)); - axolotl_session_store_session(builder->store, builder->remote_address, record); - axolotl_identity_save_identity(builder->store, - builder->remote_address->name, builder->remote_address->name_len, - their_identity_key); - -complete: - AXOLOTL_UNREF(record); - AXOLOTL_UNREF(our_base_key); - AXOLOTL_UNREF(our_identity_key); - AXOLOTL_UNREF(parameters); - axolotl_unlock(builder->global_context); - return result; -} - -int session_builder_process_key_exchange_message(session_builder *builder, key_exchange_message *message, key_exchange_message **response_message) -{ - int result = 0; - key_exchange_message *result_response_message = 0; - - assert(builder); - assert(builder->store); - axolotl_lock(builder->global_context); - - result = axolotl_identity_is_trusted_identity(builder->store, - builder->remote_address->name, builder->remote_address->name_len, - key_exchange_message_get_identity_key(message)); - if(result < 0) { - goto complete; - } - if(result == 0) { - result = AX_ERR_UNTRUSTED_IDENTITY; - goto complete; - } - result = 0; - - if(key_exchange_message_is_initiate(message)) { - result = session_builder_process_initiate(builder, message, &result_response_message); - } - else { - result = session_builder_process_response(builder, message); - } - -complete: - if(result >= 0) { - *response_message = result_response_message; - } - else { - AXOLOTL_UNREF(result_response_message); - } - axolotl_unlock(builder->global_context); - return result; -} - -static int session_builder_process_initiate(session_builder *builder, key_exchange_message *message, key_exchange_message **response_message) -{ - int result = 0; - key_exchange_message *result_response_message = 0; - - uint32_t flags = KEY_EXCHANGE_RESPONSE_FLAG; - session_record *record = 0; - session_state *state = 0; - ratchet_identity_key_pair *identity_key_pair = 0; - ec_key_pair *our_base_key = 0; - ec_key_pair *our_ratchet_key = 0; - symmetric_axolotl_parameters *parameters = 0; - ratchet_identity_key_pair *parameters_identity_key = 0; - ec_key_pair *parameters_base_key = 0; - axolotl_buffer *parameters_public_base_key_serialized = 0; - ec_key_pair *parameters_ratchet_key = 0; - axolotl_buffer *base_key_signature = 0; - - result = axolotl_session_load_session(builder->store, &record, builder->remote_address); + result = signal_protocol_session_store_session(builder->store, builder->remote_address, record); if(result < 0) { goto complete; } - if(key_exchange_message_get_version(message) >= 3) { - ec_public_key *message_identity_key = key_exchange_message_get_identity_key(message); - ec_public_key *message_base_key = key_exchange_message_get_base_key(message); - axolotl_buffer *message_base_key_serialized = 0; - uint8_t *message_base_key_signature = 0; - - ec_public_key_serialize(&message_base_key_serialized, message_base_key); - - message_base_key_signature = key_exchange_message_get_base_key_signature(message); - - result = curve_verify_signature(message_identity_key, - axolotl_buffer_data(message_base_key_serialized), - axolotl_buffer_len(message_base_key_serialized), - message_base_key_signature, CURVE_SIGNATURE_LEN); - axolotl_buffer_free(message_base_key_serialized); - if(result < 0) { - goto complete; - } - if(result != 1) { - axolotl_log(builder->global_context, AX_LOG_WARNING, "Bad signature!"); - result = AX_ERR_INVALID_KEY; - goto complete; - } - } - - state = session_record_get_state(record); - if(!session_state_has_pending_key_exchange(state)) { - result = axolotl_identity_get_key_pair(builder->store, &identity_key_pair); - if(result < 0) { - goto complete; - } - - result = curve_generate_key_pair(builder->global_context, &our_base_key); - if(result < 0) { - goto complete; - } - - result = curve_generate_key_pair(builder->global_context, &our_ratchet_key); - if(result < 0) { - goto complete; - } - - result = symmetric_axolotl_parameters_create( - ¶meters, - identity_key_pair, - our_base_key, - our_ratchet_key, - key_exchange_message_get_base_key(message), - key_exchange_message_get_ratchet_key(message), - key_exchange_message_get_identity_key(message)); - if(result < 0) { - goto complete; - } - } - else { - result = symmetric_axolotl_parameters_create( - ¶meters, - session_state_get_pending_key_exchange_identity_key(state), - session_state_get_pending_key_exchange_base_key(state), - session_state_get_pending_key_exchange_ratchet_key(state), - key_exchange_message_get_base_key(message), - key_exchange_message_get_ratchet_key(message), - key_exchange_message_get_identity_key(message)); - if(result < 0) { - goto complete; - } - - flags |= KEY_EXCHANGE_SIMULTAENOUS_INITIATE_FLAG; - } - - if(!session_record_is_fresh(record)) { - session_record_archive_current_state(record); - } - - state = session_record_get_state(record); - result = ratcheting_session_symmetric_initialize(state, - MIN(key_exchange_message_get_max_version(message), (uint32_t)CIPHERTEXT_CURRENT_VERSION), - parameters, builder->global_context); - if(result < 0) { - goto complete; - } - - result = axolotl_session_store_session(builder->store, builder->remote_address, record); - if(result < 0) { - goto complete; - } - - result = axolotl_identity_save_identity(builder->store, - builder->remote_address->name, builder->remote_address->name_len, - key_exchange_message_get_identity_key(message)); - if(result < 0) { - goto complete; - } - - parameters_identity_key = symmetric_axolotl_parameters_get_our_identity_key(parameters); - parameters_base_key = symmetric_axolotl_parameters_get_our_base_key(parameters); - parameters_ratchet_key = symmetric_axolotl_parameters_get_our_ratchet_key(parameters); - - result = ec_public_key_serialize(¶meters_public_base_key_serialized, - ec_key_pair_get_public(parameters_base_key)); - if(result < 0) { - goto complete; - } - - result = curve_calculate_signature(builder->global_context, - &base_key_signature, - ratchet_identity_key_pair_get_private(parameters_identity_key), - axolotl_buffer_data(parameters_public_base_key_serialized), - axolotl_buffer_len(parameters_public_base_key_serialized)); - if(result < 0) { - goto complete; - } - - result = key_exchange_message_create(&result_response_message, - session_state_get_session_version(state), - key_exchange_message_get_sequence(message), - flags, - ec_key_pair_get_public(parameters_base_key), - axolotl_buffer_data(base_key_signature), - ec_key_pair_get_public(parameters_ratchet_key), - ratchet_identity_key_pair_get_public(parameters_identity_key)); - -complete: - axolotl_buffer_free(parameters_public_base_key_serialized); - axolotl_buffer_free(base_key_signature); - AXOLOTL_UNREF(our_base_key); - AXOLOTL_UNREF(our_ratchet_key); - AXOLOTL_UNREF(identity_key_pair); - AXOLOTL_UNREF(parameters); - AXOLOTL_UNREF(record); - if(result >= 0) { - *response_message = result_response_message; - } - else { - AXOLOTL_UNREF(result_response_message); - } - return result; -} - -static int session_builder_process_response(session_builder *builder, key_exchange_message *message) -{ - int result = 0; - session_record *record = 0; - session_state *state = 0; - int has_pending_key_exchange = 0; - int is_simultaneous_initiate_response = 0; - symmetric_axolotl_parameters *parameters = 0; - - result = axolotl_session_load_session(builder->store, &record, builder->remote_address); - if(result < 0) { - goto complete; - } - - state = session_record_get_state(record); - has_pending_key_exchange = session_state_has_pending_key_exchange(state); - is_simultaneous_initiate_response = key_exchange_message_is_response_for_simultaneous_initiate(message); - - if(!has_pending_key_exchange || - session_state_get_pending_key_exchange_sequence(state) != key_exchange_message_get_sequence(message)) { - axolotl_log(builder->global_context, AX_LOG_INFO, "No matching sequence for response. Is simultaneous initiate response: %d", is_simultaneous_initiate_response); - if(!is_simultaneous_initiate_response) { - result = AX_ERR_STALE_KEY_EXCHANGE; - goto complete; - } - else { - result = AX_SUCCESS; - goto complete; - } - } - - result = symmetric_axolotl_parameters_create( - ¶meters, - session_state_get_pending_key_exchange_identity_key(state), - session_state_get_pending_key_exchange_base_key(state), - session_state_get_pending_key_exchange_ratchet_key(state), - key_exchange_message_get_base_key(message), - key_exchange_message_get_ratchet_key(message), - key_exchange_message_get_identity_key(message)); - if(result < 0) { - goto complete; - } - - if(!session_record_is_fresh(record)) { - session_record_archive_current_state(record); - } - - state = session_record_get_state(record); - result = ratcheting_session_symmetric_initialize(state, - MIN(key_exchange_message_get_max_version(message), (uint32_t)CIPHERTEXT_CURRENT_VERSION), - parameters, builder->global_context); - if(result < 0) { - goto complete; - } - - result = axolotl_session_store_session(builder->store, builder->remote_address, record); - if(result < 0) { - goto complete; - } - - if(session_state_get_session_version(state) >= 3) { - ec_public_key *message_identity_key = key_exchange_message_get_identity_key(message); - ec_public_key *message_base_key = key_exchange_message_get_base_key(message); - axolotl_buffer *message_base_key_serialized = 0; - uint8_t *message_base_key_signature = 0; - - ec_public_key_serialize(&message_base_key_serialized, message_base_key); - - message_base_key_signature = key_exchange_message_get_base_key_signature(message); - - result = curve_verify_signature(message_identity_key, - axolotl_buffer_data(message_base_key_serialized), - axolotl_buffer_len(message_base_key_serialized), - message_base_key_signature, CURVE_SIGNATURE_LEN); - axolotl_buffer_free(message_base_key_serialized); - if(result < 0) { - goto complete; - } - if(result != 1) { - axolotl_log(builder->global_context, AX_LOG_WARNING, "Base key signature doesn't match!"); - result = AX_ERR_INVALID_KEY; - goto complete; - } - } - - result = axolotl_session_store_session(builder->store, builder->remote_address, record); - if(result < 0) { - goto complete; - } - - result = axolotl_identity_save_identity(builder->store, - builder->remote_address->name, builder->remote_address->name_len, - key_exchange_message_get_identity_key(message)); - if(result < 0) { - goto complete; - } - -complete: - AXOLOTL_UNREF(parameters); - AXOLOTL_UNREF(record); - return result; -} - -int session_builder_process(session_builder *builder, key_exchange_message **message) -{ - int result = 0; - key_exchange_message *result_message = 0; - int random_value = 0; - uint32_t sequence = 0; - uint32_t flags = KEY_EXCHANGE_INITIATE_FLAG; - ec_key_pair *base_key = 0; - ec_key_pair *ratchet_key = 0; - ratchet_identity_key_pair *identity_key = 0; - axolotl_buffer *base_key_public_serialized = 0; - axolotl_buffer *base_key_signature = 0; - session_record *record = 0; - session_state *state = 0; - - assert(builder); - assert(builder->store); - axolotl_lock(builder->global_context); - - result = axolotl_key_helper_get_random_sequence(&random_value, 65534, builder->global_context); - if(result < 0) { - goto complete; - } - sequence = ((uint32_t)random_value) + 1; - - result = curve_generate_key_pair(builder->global_context, &base_key); - if(result < 0) { - goto complete; - } - - result = curve_generate_key_pair(builder->global_context, &ratchet_key); - if(result < 0) { - goto complete; - } - - result = axolotl_identity_get_key_pair(builder->store, &identity_key); - if(result < 0) { - goto complete; - } - - result = ec_public_key_serialize(&base_key_public_serialized, ec_key_pair_get_public(base_key)); - if(result < 0) { - goto complete; - } - - result = curve_calculate_signature(builder->global_context, &base_key_signature, - ratchet_identity_key_pair_get_private(identity_key), - axolotl_buffer_data(base_key_public_serialized), - axolotl_buffer_len(base_key_public_serialized)); - if(result < 0) { - goto complete; - } - - if(axolotl_buffer_len(base_key_signature) != CURVE_SIGNATURE_LEN) { - result = AX_ERR_UNKNOWN; - goto complete; - } - - result = axolotl_session_load_session(builder->store, &record, builder->remote_address); - if(result < 0) { - goto complete; - } - - state = session_record_get_state(record); - session_state_set_pending_key_exchange(state, sequence, base_key, ratchet_key, identity_key); - - result = axolotl_session_store_session(builder->store, builder->remote_address, record); + result = signal_protocol_identity_save_identity(builder->store, + builder->remote_address, + their_identity_key); if(result < 0) { goto complete; } - result = key_exchange_message_create(&result_message, - 2, sequence, flags, - ec_key_pair_get_public(base_key), - axolotl_buffer_data(base_key_signature), - ec_key_pair_get_public(ratchet_key), - ratchet_identity_key_pair_get_public(identity_key)); - complete: - AXOLOTL_UNREF(record); - axolotl_buffer_free(base_key_signature); - axolotl_buffer_free(base_key_public_serialized); - AXOLOTL_UNREF(identity_key); - AXOLOTL_UNREF(ratchet_key); - AXOLOTL_UNREF(base_key); - if(result >= 0) { - *message = result_message; - } - else { - result = AX_ERR_INVALID_KEY; - AXOLOTL_UNREF(result_message); - } - axolotl_unlock(builder->global_context); + SIGNAL_UNREF(record); + SIGNAL_UNREF(our_base_key); + SIGNAL_UNREF(our_identity_key); + SIGNAL_UNREF(parameters); + signal_unlock(builder->global_context); return result; } diff --git a/libs/libaxolotl/src/session_builder.h b/libs/libaxolotl/src/session_builder.h index cfd67a1824..6e56ba24f0 100644 --- a/libs/libaxolotl/src/session_builder.h +++ b/libs/libaxolotl/src/session_builder.h @@ -2,7 +2,7 @@ #define SESSION_BUILDER_H #include <stdint.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { @@ -13,12 +13,11 @@ extern "C" { * Once a session has been established, session_cipher * can be used to encrypt/decrypt messages in that session. * - * Sessions are built from one of three different possible vectors: + * Sessions are built from one these different possible vectors: * - A session_pre_key_bundle retrieved from a server - * - A pre_key_whisper_message received from a client - * - A key_exchange_message sent to or received from a client + * - A pre_key_signal_message received from a client * - * Sessions are constructed per AXOLOTL address + * Sessions are constructed per Signal Protocol address * (recipient name + device ID tuple). Remote logical users are identified by * their recipient name, and each logical recipient can have multiple * physical devices. @@ -33,65 +32,25 @@ extern "C" { * When finished, free the returned instance by calling session_builder_free(). * * @param builder set to a freshly allocated session builder instance - * @param store the axolotl_store_context to store all state information in + * @param store the signal_protocol_store_context to store all state information in * @param remote_address the address of the remote user to build a session with * @param global_context the global library context * @return 0 on success, or negative on failure */ int session_builder_create(session_builder **builder, - axolotl_store_context *store, const axolotl_address *remote_address, - axolotl_context *global_context); - -/** - * Build a new session from a received pre_key_whisper_message. - * - * After a session is constructed in this way, the embedded whisper_message - * can be decrypted. - * - * @param message The received pre_key_whisper_message. - * @param unsigned_pre_key_id set to the unsigned pre key ID, if available. - * Return value indicates whether or not this value is available. - * @retval 0 Success, no unsigned pre key value available - * @retval 1 Success, an unsigned pre key is available - * @retval AX_ERR_INVALID_KEY_ID when there is no local pre_key_record that - * corresponds to the PreKey ID in the message. - * @retval AX_ERR_INVALID_KEY when the message is formatted incorrectly. - * @retval AX_ERR_UNTRUSTED_IDENTITY when the identity key of the sender is untrusted. - */ -int session_builder_process_pre_key_whisper_message(session_builder *builder, - session_record *record, pre_key_whisper_message *message, uint32_t *unsigned_pre_key_id); + signal_protocol_store_context *store, const signal_protocol_address *remote_address, + signal_context *global_context); /** * Build a new session from a session_pre_key_bundle retrieved from a server. * * @param bundle A pre key bundle for the destination recipient, retrieved from a server. - * @retval AX_SUCCESS Success - * @retval AX_ERR_INVALID_KEY when the session_pre_key_bundle is badly formatted. - * @retval AX_ERR_UNTRUSTED_IDENTITY when the sender's identity key is not trusted. + * @retval SG_SUCCESS Success + * @retval SG_ERR_INVALID_KEY when the session_pre_key_bundle is badly formatted. + * @retval SG_ERR_UNTRUSTED_IDENTITY when the sender's identity key is not trusted. */ int session_builder_process_pre_key_bundle(session_builder *builder, session_pre_key_bundle *bundle); -/** - * Build a new session from a key_exchange_message received from a remote client. - * - * @param message The received key_exchange_message. - * @param response_message Set to the key_exchange_message to respond with, - * or set to 0 if no response is necessary. - * @retval AX_SUCCESS Success - * @retval AX_ERR_INVALID_KEY if the received key_exchange_message is badly formatted. - * @retval AX_ERR_UNTRUSTED_IDENTITY - * @retval AX_ERR_STALE_KEY_EXCHANGE - */ -int session_builder_process_key_exchange_message(session_builder *builder, key_exchange_message *message, key_exchange_message **response_message); - -/** - * Initiate a new session by sending an initial key_exchange_message to the recipient. - * - * @param message Set to the key_exchange_message to deliver. - * @return AX_SUCCESS on success, negative on error - */ -int session_builder_process(session_builder *builder, key_exchange_message **message); - void session_builder_free(session_builder *builder); #ifdef __cplusplus diff --git a/libs/libaxolotl/src/session_builder_internal.h b/libs/libaxolotl/src/session_builder_internal.h new file mode 100644 index 0000000000..2bf8dba4e0 --- /dev/null +++ b/libs/libaxolotl/src/session_builder_internal.h @@ -0,0 +1,26 @@ +#ifndef SESSION_BUILDER_INTERNAL_H +#define SESSION_BUILDER_INTERNAL_H + +#include <stdint.h> +#include "signal_protocol_types.h" + +/** + * Build a new session from a received pre_key_signal_message. + * + * After a session is constructed in this way, the embedded signal_message + * can be decrypted. + * + * @param message The received pre_key_signal_message. + * @param unsigned_pre_key_id set to the unsigned pre key ID, if available. + * Return value indicates whether or not this value is available. + * @retval 0 Success, no unsigned pre key value available + * @retval 1 Success, an unsigned pre key is available + * @retval SG_ERR_INVALID_KEY_ID when there is no local pre_key_record that + * corresponds to the PreKey ID in the message. + * @retval SG_ERR_INVALID_KEY when the message is formatted incorrectly. + * @retval SG_ERR_UNTRUSTED_IDENTITY when the identity key of the sender is untrusted. + */ +int session_builder_process_pre_key_signal_message(session_builder *builder, + session_record *record, pre_key_signal_message *message, uint32_t *unsigned_pre_key_id); + +#endif /* SESSION_BUILDER_INTERNAL_H */ diff --git a/libs/libaxolotl/src/session_cipher.c b/libs/libaxolotl/src/session_cipher.c index c2065ef5dc..3e80788c62 100644 --- a/libs/libaxolotl/src/session_cipher.c +++ b/libs/libaxolotl/src/session_cipher.c @@ -2,28 +2,29 @@ #include <assert.h> #include <string.h> -#include "axolotl_internal.h" #include "session_builder.h" +#include "session_builder_internal.h" #include "session_record.h" #include "session_state.h" #include "ratchet.h" #include "protocol.h" +#include "signal_protocol_internal.h" struct session_cipher { - axolotl_store_context *store; - const axolotl_address *remote_address; + signal_protocol_store_context *store; + const signal_protocol_address *remote_address; session_builder *builder; - axolotl_context *global_context; - int (*decrypt_callback)(session_cipher *cipher, axolotl_buffer *plaintext, void *decrypt_context); + signal_context *global_context; + int (*decrypt_callback)(session_cipher *cipher, signal_buffer *plaintext, void *decrypt_context); int inside_callback; void *user_data; }; -static int session_cipher_decrypt_from_record_and_whisper_message(session_cipher *cipher, - session_record *record, whisper_message *ciphertext, axolotl_buffer **plaintext); -static int session_cipher_decrypt_from_state_and_whisper_message(session_cipher *cipher, - session_state *state, whisper_message *ciphertext, axolotl_buffer **plaintext); +static int session_cipher_decrypt_from_record_and_signal_message(session_cipher *cipher, + session_record *record, signal_message *ciphertext, signal_buffer **plaintext); +static int session_cipher_decrypt_from_state_and_signal_message(session_cipher *cipher, + session_state *state, signal_message *ciphertext, signal_buffer **plaintext); static int session_cipher_get_or_create_chain_key(session_cipher *cipher, ratchet_chain_key **chain_key, @@ -31,22 +32,22 @@ static int session_cipher_get_or_create_chain_key(session_cipher *cipher, static int session_cipher_get_or_create_message_keys(ratchet_message_keys *message_keys, session_state *state, ec_public_key *their_ephemeral, ratchet_chain_key *chain_key, uint32_t counter, - axolotl_context *global_context); + signal_context *global_context); static int session_cipher_get_ciphertext(session_cipher *cipher, - axolotl_buffer **ciphertext, + signal_buffer **ciphertext, uint32_t version, ratchet_message_keys *message_keys, const uint8_t *plaintext, size_t plaintext_len); static int session_cipher_get_plaintext(session_cipher *cipher, - axolotl_buffer **plaintext, + signal_buffer **plaintext, uint32_t version, ratchet_message_keys *message_keys, const uint8_t *ciphertext, size_t ciphertext_len); -static int session_cipher_decrypt_callback(session_cipher *cipher, axolotl_buffer *plaintext, void *decrypt_context); +static int session_cipher_decrypt_callback(session_cipher *cipher, signal_buffer *plaintext, void *decrypt_context); int session_cipher_create(session_cipher **cipher, - axolotl_store_context *store, const axolotl_address *remote_address, - axolotl_context *global_context) + signal_protocol_store_context *store, const signal_protocol_address *remote_address, + signal_context *global_context) { int result = 0; session_builder *builder = 0; @@ -62,7 +63,7 @@ int session_cipher_create(session_cipher **cipher, result_cipher = malloc(sizeof(session_cipher)); if(!result_cipher) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result_cipher, 0, sizeof(session_cipher)); @@ -88,7 +89,7 @@ void *session_cipher_get_user_data(session_cipher *cipher) } void session_cipher_set_decryption_callback(session_cipher *cipher, - int (*callback)(session_cipher *cipher, axolotl_buffer *plaintext, void *decrypt_context)) + int (*callback)(session_cipher *cipher, signal_buffer *plaintext, void *decrypt_context)) { assert(cipher); cipher->decrypt_callback = callback; @@ -107,37 +108,37 @@ int session_cipher_encrypt(session_cipher *cipher, ec_public_key *sender_ephemeral = 0; uint32_t previous_counter = 0; uint32_t session_version = 0; - axolotl_buffer *ciphertext = 0; + signal_buffer *ciphertext = 0; uint32_t chain_key_index = 0; ec_public_key *local_identity_key = 0; ec_public_key *remote_identity_key = 0; - whisper_message *message = 0; - pre_key_whisper_message *pre_key_message = 0; + signal_message *message = 0; + pre_key_signal_message *pre_key_message = 0; uint8_t *ciphertext_data = 0; size_t ciphertext_len = 0; assert(cipher); - axolotl_lock(cipher->global_context); + signal_lock(cipher->global_context); if(cipher->inside_callback == 1) { - result = AX_ERR_INVAL; + result = SG_ERR_INVAL; goto complete; } - result = axolotl_session_load_session(cipher->store, &record, cipher->remote_address); + result = signal_protocol_session_load_session(cipher->store, &record, cipher->remote_address); if(result < 0) { goto complete; } state = session_record_get_state(record); if(!state) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } chain_key = session_state_get_sender_chain_key(state); if(!chain_key) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } @@ -148,7 +149,7 @@ int session_cipher_encrypt(session_cipher *cipher, sender_ephemeral = session_state_get_sender_ratchet_key(state); if(!sender_ephemeral) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } @@ -162,24 +163,24 @@ int session_cipher_encrypt(session_cipher *cipher, if(result < 0) { goto complete; } - ciphertext_data = axolotl_buffer_data(ciphertext); - ciphertext_len = axolotl_buffer_len(ciphertext); + ciphertext_data = signal_buffer_data(ciphertext); + ciphertext_len = signal_buffer_len(ciphertext); chain_key_index = ratchet_chain_key_get_index(chain_key); local_identity_key = session_state_get_local_identity_key(state); if(!local_identity_key) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } remote_identity_key = session_state_get_remote_identity_key(state); if(!remote_identity_key) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } - result = whisper_message_create(&message, + result = signal_message_create(&message, session_version, message_keys.mac_key, sizeof(message_keys.mac_key), sender_ephemeral, @@ -206,11 +207,11 @@ int session_cipher_encrypt(session_cipher *cipher, base_key = session_state_unacknowledged_pre_key_message_get_base_key(state); if(!base_key) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } - result = pre_key_whisper_message_create(&pre_key_message, + result = pre_key_signal_message_create(&pre_key_message, session_version, local_registration_id, (has_pre_key_id ? &pre_key_id : 0), signed_pre_key_id, base_key, local_identity_key, message, @@ -218,7 +219,7 @@ int session_cipher_encrypt(session_cipher *cipher, if(result < 0) { goto complete; } - AXOLOTL_UNREF(message); + SIGNAL_UNREF(message); message = 0; } @@ -232,7 +233,7 @@ int session_cipher_encrypt(session_cipher *cipher, goto complete; } - result = axolotl_session_store_session(cipher->store, cipher->remote_address, record); + result = signal_protocol_session_store_session(cipher->store, cipher->remote_address, record); complete: if(result >= 0) { @@ -244,48 +245,48 @@ complete: } } else { - AXOLOTL_UNREF(pre_key_message); - AXOLOTL_UNREF(message); - } - axolotl_buffer_free(ciphertext); - AXOLOTL_UNREF(next_chain_key); - AXOLOTL_UNREF(record); - axolotl_explicit_bzero(&message_keys, sizeof(ratchet_message_keys)); - axolotl_unlock(cipher->global_context); + SIGNAL_UNREF(pre_key_message); + SIGNAL_UNREF(message); + } + signal_buffer_free(ciphertext); + SIGNAL_UNREF(next_chain_key); + SIGNAL_UNREF(record); + signal_explicit_bzero(&message_keys, sizeof(ratchet_message_keys)); + signal_unlock(cipher->global_context); return result; } -int session_cipher_decrypt_pre_key_whisper_message(session_cipher *cipher, - pre_key_whisper_message *ciphertext, void *decrypt_context, - axolotl_buffer **plaintext) +int session_cipher_decrypt_pre_key_signal_message(session_cipher *cipher, + pre_key_signal_message *ciphertext, void *decrypt_context, + signal_buffer **plaintext) { int result = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; session_record *record = 0; int has_unsigned_pre_key_id = 0; uint32_t unsigned_pre_key_id = 0; assert(cipher); - axolotl_lock(cipher->global_context); + signal_lock(cipher->global_context); if(cipher->inside_callback == 1) { - result = AX_ERR_INVAL; + result = SG_ERR_INVAL; goto complete; } - result = axolotl_session_load_session(cipher->store, &record, cipher->remote_address); + result = signal_protocol_session_load_session(cipher->store, &record, cipher->remote_address); if(result < 0) { goto complete; } - result = session_builder_process_pre_key_whisper_message(cipher->builder, record, ciphertext, &unsigned_pre_key_id); + result = session_builder_process_pre_key_signal_message(cipher->builder, record, ciphertext, &unsigned_pre_key_id); if(result < 0) { goto complete; } has_unsigned_pre_key_id = result; - result = session_cipher_decrypt_from_record_and_whisper_message(cipher, record, - pre_key_whisper_message_get_whisper_message(ciphertext), + result = session_cipher_decrypt_from_record_and_signal_message(cipher, record, + pre_key_signal_message_get_signal_message(ciphertext), &result_buf); if(result < 0) { goto complete; @@ -296,63 +297,63 @@ int session_cipher_decrypt_pre_key_whisper_message(session_cipher *cipher, goto complete; } - result = axolotl_session_store_session(cipher->store, cipher->remote_address, record); + result = signal_protocol_session_store_session(cipher->store, cipher->remote_address, record); if(result < 0) { goto complete; } if(has_unsigned_pre_key_id) { - result = axolotl_pre_key_remove_key(cipher->store, unsigned_pre_key_id); + result = signal_protocol_pre_key_remove_key(cipher->store, unsigned_pre_key_id); if(result < 0) { goto complete; } } complete: - AXOLOTL_UNREF(record); + SIGNAL_UNREF(record); if(result >= 0) { *plaintext = result_buf; } else { - axolotl_buffer_free(result_buf); + signal_buffer_free(result_buf); } - axolotl_unlock(cipher->global_context); + signal_unlock(cipher->global_context); return result; } -int session_cipher_decrypt_whisper_message(session_cipher *cipher, - whisper_message *ciphertext, void *decrypt_context, - axolotl_buffer **plaintext) +int session_cipher_decrypt_signal_message(session_cipher *cipher, + signal_message *ciphertext, void *decrypt_context, + signal_buffer **plaintext) { int result = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; session_record *record = 0; assert(cipher); - axolotl_lock(cipher->global_context); + signal_lock(cipher->global_context); if(cipher->inside_callback == 1) { - result = AX_ERR_INVAL; + result = SG_ERR_INVAL; goto complete; } - result = axolotl_session_contains_session(cipher->store, cipher->remote_address); + result = signal_protocol_session_contains_session(cipher->store, cipher->remote_address); if(result == 0) { - axolotl_log(cipher->global_context, AX_LOG_WARNING, "No session for: %s:%d", cipher->remote_address->name, cipher->remote_address->device_id); - result = AX_ERR_NO_SESSION; + signal_log(cipher->global_context, SG_LOG_WARNING, "No session for: %s:%d", cipher->remote_address->name, cipher->remote_address->device_id); + result = SG_ERR_NO_SESSION; goto complete; } else if(result < 0) { goto complete; } - result = axolotl_session_load_session(cipher->store, &record, + result = signal_protocol_session_load_session(cipher->store, &record, cipher->remote_address); if(result < 0) { goto complete; } - result = session_cipher_decrypt_from_record_and_whisper_message( + result = session_cipher_decrypt_from_record_and_signal_message( cipher, record, ciphertext, &result_buf); if(result < 0) { goto complete; @@ -363,32 +364,32 @@ int session_cipher_decrypt_whisper_message(session_cipher *cipher, goto complete; } - result = axolotl_session_store_session(cipher->store, + result = signal_protocol_session_store_session(cipher->store, cipher->remote_address, record); complete: - AXOLOTL_UNREF(record); + SIGNAL_UNREF(record); if(result >= 0) { *plaintext = result_buf; } else { - axolotl_buffer_free(result_buf); + signal_buffer_free(result_buf); } - axolotl_unlock(cipher->global_context); + signal_unlock(cipher->global_context); return result; } -static int session_cipher_decrypt_from_record_and_whisper_message(session_cipher *cipher, - session_record *record, whisper_message *ciphertext, axolotl_buffer **plaintext) +static int session_cipher_decrypt_from_record_and_signal_message(session_cipher *cipher, + session_record *record, signal_message *ciphertext, signal_buffer **plaintext) { int result = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; session_state *state = 0; session_state *state_copy = 0; session_record_state_node *previous_states_node = 0; assert(cipher); - axolotl_lock(cipher->global_context); + signal_lock(cipher->global_context); state = session_record_get_state(record); if(state) { @@ -399,16 +400,16 @@ static int session_cipher_decrypt_from_record_and_whisper_message(session_cipher //TODO Collect and log invalid message errors if totally unsuccessful - result = session_cipher_decrypt_from_state_and_whisper_message(cipher, state_copy, ciphertext, &result_buf); - if(result < 0 && result != AX_ERR_INVALID_MESSAGE) { + result = session_cipher_decrypt_from_state_and_signal_message(cipher, state_copy, ciphertext, &result_buf); + if(result < 0 && result != SG_ERR_INVALID_MESSAGE) { goto complete; } - if(result >= AX_SUCCESS) { + if(result >= SG_SUCCESS) { session_record_set_state(record, state_copy); goto complete; } - AXOLOTL_UNREF(state_copy); + SIGNAL_UNREF(state_copy); } previous_states_node = session_record_get_previous_states_head(record); @@ -420,41 +421,41 @@ static int session_cipher_decrypt_from_record_and_whisper_message(session_cipher goto complete; } - result = session_cipher_decrypt_from_state_and_whisper_message(cipher, state_copy, ciphertext, &result_buf); - if(result < 0 && result != AX_ERR_INVALID_MESSAGE) { + result = session_cipher_decrypt_from_state_and_signal_message(cipher, state_copy, ciphertext, &result_buf); + if(result < 0 && result != SG_ERR_INVALID_MESSAGE) { goto complete; } - if(result >= AX_SUCCESS) { + if(result >= SG_SUCCESS) { session_record_get_previous_states_remove(record, previous_states_node); result = session_record_promote_state(record, state_copy); goto complete; } - AXOLOTL_UNREF(state_copy); + SIGNAL_UNREF(state_copy); previous_states_node = session_record_get_previous_states_next(previous_states_node); } - axolotl_log(cipher->global_context, AX_LOG_WARNING, "No valid sessions"); - result = AX_ERR_INVALID_MESSAGE; + signal_log(cipher->global_context, SG_LOG_WARNING, "No valid sessions"); + result = SG_ERR_INVALID_MESSAGE; complete: - AXOLOTL_UNREF(state_copy); + SIGNAL_UNREF(state_copy); if(result >= 0) { *plaintext = result_buf; } else { - axolotl_buffer_free(result_buf); + signal_buffer_free(result_buf); } - axolotl_unlock(cipher->global_context); + signal_unlock(cipher->global_context); return result; } -static int session_cipher_decrypt_from_state_and_whisper_message(session_cipher *cipher, - session_state *state, whisper_message *ciphertext, axolotl_buffer **plaintext) +static int session_cipher_decrypt_from_state_and_signal_message(session_cipher *cipher, + session_state *state, signal_message *ciphertext, signal_buffer **plaintext) { int result = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; ec_public_key *their_ephemeral = 0; uint32_t counter = 0; ratchet_chain_key *chain_key = 0; @@ -463,30 +464,30 @@ static int session_cipher_decrypt_from_state_and_whisper_message(session_cipher uint32_t session_version = 0; ec_public_key *remote_identity_key = 0; ec_public_key *local_identity_key = 0; - axolotl_buffer *ciphertext_body = 0; + signal_buffer *ciphertext_body = 0; if(!session_state_has_sender_chain(state)) { - axolotl_log(cipher->global_context, AX_LOG_WARNING, "Uninitialized session!"); - result = AX_ERR_INVALID_MESSAGE; + signal_log(cipher->global_context, SG_LOG_WARNING, "Uninitialized session!"); + result = SG_ERR_INVALID_MESSAGE; goto complete; } - message_version = whisper_message_get_message_version(ciphertext); + message_version = signal_message_get_message_version(ciphertext); session_version = session_state_get_session_version(state); if(message_version != session_version) { - axolotl_log(cipher->global_context, AX_LOG_WARNING, "Message version %d, but session version %d", message_version, session_version); - result = AX_ERR_INVALID_MESSAGE; + signal_log(cipher->global_context, SG_LOG_WARNING, "Message version %d, but session version %d", message_version, session_version); + result = SG_ERR_INVALID_MESSAGE; goto complete; } - their_ephemeral = whisper_message_get_sender_ratchet_key(ciphertext); + their_ephemeral = signal_message_get_sender_ratchet_key(ciphertext); if(!their_ephemeral) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } - counter = whisper_message_get_counter(ciphertext); + counter = signal_message_get_counter(ciphertext); result = session_cipher_get_or_create_chain_key(cipher, &chain_key, state, their_ephemeral); if(result < 0) { @@ -501,40 +502,40 @@ static int session_cipher_decrypt_from_state_and_whisper_message(session_cipher remote_identity_key = session_state_get_remote_identity_key(state); if(!remote_identity_key) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } local_identity_key = session_state_get_local_identity_key(state); if(!local_identity_key) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } - result = whisper_message_verify_mac(ciphertext, message_version, + result = signal_message_verify_mac(ciphertext, message_version, remote_identity_key, local_identity_key, message_keys.mac_key, sizeof(message_keys.mac_key), cipher->global_context); if(result != 1) { if(result == 0) { - axolotl_log(cipher->global_context, AX_LOG_WARNING, "Message mac not verified"); - result = AX_ERR_INVALID_MESSAGE; + signal_log(cipher->global_context, SG_LOG_WARNING, "Message mac not verified"); + result = SG_ERR_INVALID_MESSAGE; } else if(result < 0) { - axolotl_log(cipher->global_context, AX_LOG_WARNING, "Error attempting to verify message mac"); + signal_log(cipher->global_context, SG_LOG_WARNING, "Error attempting to verify message mac"); } goto complete; } - ciphertext_body = whisper_message_get_body(ciphertext); + ciphertext_body = signal_message_get_body(ciphertext); if(!ciphertext_body) { - axolotl_log(cipher->global_context, AX_LOG_WARNING, "Message body does not exist"); - result = AX_ERR_INVALID_MESSAGE; + signal_log(cipher->global_context, SG_LOG_WARNING, "Message body does not exist"); + result = SG_ERR_INVALID_MESSAGE; goto complete; } result = session_cipher_get_plaintext(cipher, &result_buf, message_version, &message_keys, - axolotl_buffer_data(ciphertext_body), axolotl_buffer_len(ciphertext_body)); + signal_buffer_data(ciphertext_body), signal_buffer_len(ciphertext_body)); if(result < 0) { goto complete; } @@ -542,14 +543,14 @@ static int session_cipher_decrypt_from_state_and_whisper_message(session_cipher session_state_clear_unacknowledged_pre_key_message(state); complete: - AXOLOTL_UNREF(chain_key); + SIGNAL_UNREF(chain_key); if(result >= 0) { *plaintext = result_buf; } else { - axolotl_buffer_free(result_buf); + signal_buffer_free(result_buf); } - axolotl_explicit_bzero(&message_keys, sizeof(ratchet_message_keys)); + signal_explicit_bzero(&message_keys, sizeof(ratchet_message_keys)); return result; } @@ -571,19 +572,19 @@ static int session_cipher_get_or_create_chain_key(session_cipher *cipher, result_key = session_state_get_receiver_chain_key(state, their_ephemeral); if(result_key) { - AXOLOTL_REF(result_key); + SIGNAL_REF(result_key); goto complete; } root_key = session_state_get_root_key(state); if(!root_key) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } our_ephemeral = session_state_get_sender_ratchet_key_pair(state); if(!our_ephemeral) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } @@ -615,7 +616,7 @@ static int session_cipher_get_or_create_chain_key(session_cipher *cipher, previous_sender_chain_key = session_state_get_sender_chain_key(state); if(!previous_sender_chain_key) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } @@ -626,26 +627,26 @@ static int session_cipher_get_or_create_chain_key(session_cipher *cipher, session_state_set_sender_chain(state, our_new_ephemeral, sender_chain_key); result_key = receiver_chain_key; - AXOLOTL_REF(result_key); + SIGNAL_REF(result_key); complete: - AXOLOTL_UNREF(receiver_root_key); - AXOLOTL_UNREF(receiver_chain_key); - AXOLOTL_UNREF(sender_root_key); - AXOLOTL_UNREF(sender_chain_key); - AXOLOTL_UNREF(our_new_ephemeral); + SIGNAL_UNREF(receiver_root_key); + SIGNAL_UNREF(receiver_chain_key); + SIGNAL_UNREF(sender_root_key); + SIGNAL_UNREF(sender_chain_key); + SIGNAL_UNREF(our_new_ephemeral); if(result >= 0) { *chain_key = result_key; } else { - AXOLOTL_UNREF(result_key); + SIGNAL_UNREF(result_key); } return result; } static int session_cipher_get_or_create_message_keys(ratchet_message_keys *message_keys, session_state *state, ec_public_key *their_ephemeral, - ratchet_chain_key *chain_key, uint32_t counter, axolotl_context *global_context) + ratchet_chain_key *chain_key, uint32_t counter, signal_context *global_context) { int result = 0; ratchet_chain_key *cur_chain_key = 0; @@ -659,20 +660,20 @@ static int session_cipher_get_or_create_message_keys(ratchet_message_keys *messa goto complete; } - axolotl_log(global_context, AX_LOG_WARNING, "Received message with old counter: %d, %d", + signal_log(global_context, SG_LOG_WARNING, "Received message with old counter: %d, %d", ratchet_chain_key_get_index(chain_key), counter); - result = AX_ERR_DUPLICATE_MESSAGE; + result = SG_ERR_DUPLICATE_MESSAGE; goto complete; } if(counter - ratchet_chain_key_get_index(chain_key) > 2000) { - axolotl_log(global_context, AX_LOG_WARNING, "Over 2000 messages into the future!"); - result = AX_ERR_INVALID_MESSAGE; + signal_log(global_context, SG_LOG_WARNING, "Over 2000 messages into the future!"); + result = SG_ERR_INVALID_MESSAGE; goto complete; } cur_chain_key = chain_key; - AXOLOTL_REF(cur_chain_key); + SIGNAL_REF(cur_chain_key); while(ratchet_chain_key_get_index(cur_chain_key) < counter) { result = ratchet_chain_key_get_message_keys(cur_chain_key, &message_keys_result); @@ -689,7 +690,7 @@ static int session_cipher_get_or_create_message_keys(ratchet_message_keys *messa if(result < 0) { goto complete; } - AXOLOTL_UNREF(cur_chain_key); + SIGNAL_UNREF(cur_chain_key); cur_chain_key = next_chain_key; next_chain_key = 0; } @@ -713,9 +714,9 @@ complete: if(result >= 0) { memcpy(message_keys, &message_keys_result, sizeof(ratchet_message_keys)); } - AXOLOTL_UNREF(cur_chain_key); - AXOLOTL_UNREF(next_chain_key); - axolotl_explicit_bzero(&message_keys_result, sizeof(ratchet_message_keys)); + SIGNAL_UNREF(cur_chain_key); + SIGNAL_UNREF(next_chain_key); + signal_explicit_bzero(&message_keys_result, sizeof(ratchet_message_keys)); return result; } @@ -727,16 +728,16 @@ int session_cipher_get_remote_registration_id(session_cipher *cipher, uint32_t * session_state *state = 0; assert(cipher); - axolotl_lock(cipher->global_context); + signal_lock(cipher->global_context); - result = axolotl_session_load_session(cipher->store, &record, cipher->remote_address); + result = signal_protocol_session_load_session(cipher->store, &record, cipher->remote_address); if(result < 0) { goto complete; } state = session_record_get_state(record); if(!state) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } @@ -746,7 +747,7 @@ complete: if(result >= 0) { *remote_id = id_result; } - axolotl_unlock(cipher->global_context); + signal_unlock(cipher->global_context); return result; } @@ -758,25 +759,25 @@ int session_cipher_get_session_version(session_cipher *cipher, uint32_t *version session_state *state = 0; assert(cipher); - axolotl_lock(cipher->global_context); + signal_lock(cipher->global_context); - result = axolotl_session_contains_session(cipher->store, cipher->remote_address); + result = signal_protocol_session_contains_session(cipher->store, cipher->remote_address); if(result != 1) { if(result == 0) { - axolotl_log(cipher->global_context, AX_LOG_WARNING, "No session for: %s:%d", cipher->remote_address->name, cipher->remote_address->device_id); - result = AX_ERR_NO_SESSION; + signal_log(cipher->global_context, SG_LOG_WARNING, "No session for: %s:%d", cipher->remote_address->name, cipher->remote_address->device_id); + result = SG_ERR_NO_SESSION; } goto complete; } - result = axolotl_session_load_session(cipher->store, &record, cipher->remote_address); + result = signal_protocol_session_load_session(cipher->store, &record, cipher->remote_address); if(result < 0) { goto complete; } state = session_record_get_state(record); if(!state) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } @@ -786,21 +787,21 @@ complete: if(result >= 0) { *version = version_result; } - axolotl_unlock(cipher->global_context); + signal_unlock(cipher->global_context); return result; } static int session_cipher_get_ciphertext(session_cipher *cipher, - axolotl_buffer **ciphertext, + signal_buffer **ciphertext, uint32_t version, ratchet_message_keys *message_keys, const uint8_t *plaintext, size_t plaintext_len) { int result = 0; - axolotl_buffer *output = 0; + signal_buffer *output = 0; if(version >= 3) { - result = axolotl_encrypt(cipher->global_context, - &output, AX_CIPHER_AES_CBC_PKCS5, + result = signal_encrypt(cipher->global_context, + &output, SG_CIPHER_AES_CBC_PKCS5, message_keys->cipher_key, sizeof(message_keys->cipher_key), message_keys->iv, sizeof(message_keys->iv), plaintext, plaintext_len); @@ -813,8 +814,8 @@ static int session_cipher_get_ciphertext(session_cipher *cipher, iv[1] = (uint8_t)(message_keys->counter >> 16); iv[0] = (uint8_t)(message_keys->counter >> 24); - result = axolotl_encrypt(cipher->global_context, - &output, AX_CIPHER_AES_CTR_NOPADDING, + result = signal_encrypt(cipher->global_context, + &output, SG_CIPHER_AES_CTR_NOPADDING, message_keys->cipher_key, sizeof(message_keys->cipher_key), iv, sizeof(iv), plaintext, plaintext_len); @@ -828,16 +829,16 @@ static int session_cipher_get_ciphertext(session_cipher *cipher, } static int session_cipher_get_plaintext(session_cipher *cipher, - axolotl_buffer **plaintext, + signal_buffer **plaintext, uint32_t version, ratchet_message_keys *message_keys, const uint8_t *ciphertext, size_t ciphertext_len) { int result = 0; - axolotl_buffer *output = 0; + signal_buffer *output = 0; if(version >= 3) { - result = axolotl_decrypt(cipher->global_context, - &output, AX_CIPHER_AES_CBC_PKCS5, + result = signal_decrypt(cipher->global_context, + &output, SG_CIPHER_AES_CBC_PKCS5, message_keys->cipher_key, sizeof(message_keys->cipher_key), message_keys->iv, sizeof(message_keys->iv), ciphertext, ciphertext_len); @@ -850,8 +851,8 @@ static int session_cipher_get_plaintext(session_cipher *cipher, iv[1] = (uint8_t)(message_keys->counter >> 16); iv[0] = (uint8_t)(message_keys->counter >> 24); - result = axolotl_decrypt(cipher->global_context, - &output, AX_CIPHER_AES_CTR_NOPADDING, + result = signal_decrypt(cipher->global_context, + &output, SG_CIPHER_AES_CTR_NOPADDING, message_keys->cipher_key, sizeof(message_keys->cipher_key), iv, sizeof(iv), ciphertext, ciphertext_len); @@ -864,7 +865,7 @@ static int session_cipher_get_plaintext(session_cipher *cipher, return result; } -static int session_cipher_decrypt_callback(session_cipher *cipher, axolotl_buffer *plaintext, void *decrypt_context) +static int session_cipher_decrypt_callback(session_cipher *cipher, signal_buffer *plaintext, void *decrypt_context) { int result = 0; if(cipher->decrypt_callback) { diff --git a/libs/libaxolotl/src/session_cipher.h b/libs/libaxolotl/src/session_cipher.h index 9e4e61b6cf..0c1cd47f89 100644 --- a/libs/libaxolotl/src/session_cipher.h +++ b/libs/libaxolotl/src/session_cipher.h @@ -3,14 +3,14 @@ #include <stdint.h> #include <stddef.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { #endif /** - * The main entry point for Axolotl encrypt/decrypt operations. + * The main entry point for Signal Protocol encrypt/decrypt operations. * * Once a session has been established with session_builder, * this class can be used for all encrypt/decrypt operations within @@ -28,14 +28,14 @@ extern "C" { * When finished, free the returned instance by calling session_cipher_free(). * * @param cipher set to a freshly allocated session cipher instance - * @param store the axolotl_store_context to store all state information in + * @param store the signal_protocol_store_context to store all state information in * @param remote_address the remote address that messages will be encrypted to or decrypted from. * @param global_context the global library context * @return 0 on success, or negative on failure */ int session_cipher_create(session_cipher **cipher, - axolotl_store_context *store, const axolotl_address *remote_address, - axolotl_context *global_context); + signal_protocol_store_context *store, const signal_protocol_address *remote_address, + signal_context *global_context); /** * Set the optional user data pointer for the session cipher. @@ -57,8 +57,8 @@ void *session_cipher_get_user_data(session_cipher *cipher); * Set the callback function that is called during the decrypt process. * * The callback function is called from within - * session_cipher_decrypt_pre_key_whisper_message() and - * session_cipher_decrypt_whisper_message() after decryption is complete + * session_cipher_decrypt_pre_key_signal_message() and + * session_cipher_decrypt_signal_message() after decryption is complete * but before the updated session state has been committed to the session * store. If the callback function returns a negative value, then the * decrypt function will immediately fail with an error. @@ -72,7 +72,7 @@ void *session_cipher_get_user_data(session_cipher *cipher); * @param user_data user data pointer provided to the callback */ void session_cipher_set_decryption_callback(session_cipher *cipher, - int (*callback)(session_cipher *cipher, axolotl_buffer *plaintext, void *decrypt_context)); + int (*callback)(session_cipher *cipher, signal_buffer *plaintext, void *decrypt_context)); /** * Encrypt a message. @@ -81,7 +81,7 @@ void session_cipher_set_decryption_callback(session_cipher *cipher, * @param padded_message_len The length of the data pointed to by padded_message * @param encrypted_message Set to a ciphertext message encrypted to the recipient+device tuple. * - * @return AX_SUCCESS on success, negative on error + * @return SG_SUCCESS on success, negative on error */ int session_cipher_encrypt(session_cipher *cipher, const uint8_t *padded_message, size_t padded_message_len, @@ -90,50 +90,50 @@ int session_cipher_encrypt(session_cipher *cipher, /** * Decrypt a message. * - * @param ciphertext The pre_key_whisper_message to decrypt. + * @param ciphertext The pre_key_signal_message to decrypt. * @param decrypt_context Optional context pointer associated with the * ciphertext, which is passed to the decryption callback function * @param plaintext Set to a newly allocated buffer containing the plaintext. * - * @retval AX_SUCCESS Success - * @retval AX_ERR_INVALID_MESSAGE if the input is not valid ciphertext. - * @retval AX_ERR_DUPLICATE_MESSAGE if the input is a message that has already been received. - * @retval AX_ERR_LEGACY_MESSAGE if the input is a message formatted by a protocol version that + * @retval SG_SUCCESS Success + * @retval SG_ERR_INVALID_MESSAGE if the input is not valid ciphertext. + * @retval SG_ERR_DUPLICATE_MESSAGE if the input is a message that has already been received. + * @retval SG_ERR_LEGACY_MESSAGE if the input is a message formatted by a protocol version that * is no longer supported. - * @retval AX_ERR_INVALID_KEY_ID when there is no local pre_key_record + * @retval SG_ERR_INVALID_KEY_ID when there is no local pre_key_record * that corresponds to the pre key ID in the message. - * @retval AX_ERR_INVALID_KEY when the message is formatted incorrectly. - * @retval AX_ERR_UNTRUSTED_IDENTITY when the identity key of the sender is untrusted. + * @retval SG_ERR_INVALID_KEY when the message is formatted incorrectly. + * @retval SG_ERR_UNTRUSTED_IDENTITY when the identity key of the sender is untrusted. */ -int session_cipher_decrypt_pre_key_whisper_message(session_cipher *cipher, - pre_key_whisper_message *ciphertext, void *decrypt_context, - axolotl_buffer **plaintext); +int session_cipher_decrypt_pre_key_signal_message(session_cipher *cipher, + pre_key_signal_message *ciphertext, void *decrypt_context, + signal_buffer **plaintext); /** * Decrypt a message. * - * @param ciphertext The whisper_message to decrypt. + * @param ciphertext The signal_message to decrypt. * @param decrypt_context Optional context pointer associated with the * ciphertext, which is passed to the decryption callback function * @param plaintext Set to a newly allocated buffer containing the plaintext. * - * @retval AX_SUCCESS Success - * @retval AX_ERR_INVALID_MESSAGE if the input is not valid ciphertext. - * @retval AX_ERR_DUPLICATE_MESSAGE if the input is a message that has already been received. - * @retval AX_ERR_LEGACY_MESSAGE if the input is a message formatted by a protocol version that + * @retval SG_SUCCESS Success + * @retval SG_ERR_INVALID_MESSAGE if the input is not valid ciphertext. + * @retval SG_ERR_DUPLICATE_MESSAGE if the input is a message that has already been received. + * @retval SG_ERR_LEGACY_MESSAGE if the input is a message formatted by a protocol version that * is no longer supported. - * @retval AX_ERR_NO_SESSION if there is no established session for this contact. + * @retval SG_ERR_NO_SESSION if there is no established session for this contact. */ -int session_cipher_decrypt_whisper_message(session_cipher *cipher, - whisper_message *ciphertext, void *decrypt_context, - axolotl_buffer **plaintext); +int session_cipher_decrypt_signal_message(session_cipher *cipher, + signal_message *ciphertext, void *decrypt_context, + signal_buffer **plaintext); /** * Gets the remote registration ID for this session cipher. * * @param remote_id Set to the value of the remote registration ID * - * @return AX_SUCCESS on success, negative on error + * @return SG_SUCCESS on success, negative on error */ int session_cipher_get_remote_registration_id(session_cipher *cipher, uint32_t *remote_id); @@ -142,8 +142,8 @@ int session_cipher_get_remote_registration_id(session_cipher *cipher, uint32_t * * * @param version Set to the value of the session version * - * @retval AX_SUCCESS Success - * @retval AX_ERR_NO_SESSION if no session could be found + * @retval SG_SUCCESS Success + * @retval SG_ERR_NO_SESSION if no session could be found */ int session_cipher_get_session_version(session_cipher *cipher, uint32_t *version); diff --git a/libs/libaxolotl/src/session_pre_key.c b/libs/libaxolotl/src/session_pre_key.c index 333d2df6ce..416ed6a1f5 100644 --- a/libs/libaxolotl/src/session_pre_key.c +++ b/libs/libaxolotl/src/session_pre_key.c @@ -4,18 +4,18 @@ #include <string.h> #include <assert.h> -#include "axolotl_internal.h" #include "curve.h" #include "LocalStorageProtocol.pb-c.h" +#include "signal_protocol_internal.h" struct session_pre_key { - axolotl_type_base base; + signal_type_base base; uint32_t id; ec_key_pair *key_pair; }; struct session_signed_pre_key { - axolotl_type_base base; + signal_type_base base; uint32_t id; ec_key_pair *key_pair; uint64_t timestamp; @@ -24,14 +24,14 @@ struct session_signed_pre_key { }; struct session_pre_key_bundle { - axolotl_type_base base; + signal_type_base base; uint32_t registration_id; int device_id; uint32_t pre_key_id; ec_public_key *pre_key_public; uint32_t signed_pre_key_id; ec_public_key *signed_pre_key_public; - axolotl_buffer *signed_pre_key_signature; + signal_buffer *signed_pre_key_signature; ec_public_key *identity_key; }; @@ -45,33 +45,38 @@ int session_pre_key_create(session_pre_key **pre_key, uint32_t id, ec_key_pair * result = malloc(sizeof(session_pre_key)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result, 0, sizeof(session_pre_key)); - AXOLOTL_INIT(result, session_pre_key_destroy); + SIGNAL_INIT(result, session_pre_key_destroy); result->id = id; - AXOLOTL_REF(key_pair); + SIGNAL_REF(key_pair); result->key_pair = key_pair; *pre_key = result; return 0; } -int session_pre_key_serialize(axolotl_buffer **buffer, const session_pre_key *pre_key) +int session_pre_key_serialize(signal_buffer **buffer, const session_pre_key *pre_key) { int result = 0; size_t result_size = 0; Textsecure__PreKeyRecordStructure record = TEXTSECURE__PRE_KEY_RECORD_STRUCTURE__INIT; - axolotl_buffer *public_buf = 0; - axolotl_buffer *private_buf = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *public_buf = 0; + signal_buffer *private_buf = 0; + signal_buffer *result_buf = 0; ec_public_key *public_key = 0; ec_private_key *private_key = 0; size_t len = 0; uint8_t *data = 0; + if(!pre_key) { + result = SG_ERR_INVAL; + goto complete; + } + public_key = ec_key_pair_get_public(pre_key->key_pair); result = ec_public_key_serialize(&public_buf, public_key); if(result < 0) { @@ -88,36 +93,36 @@ int session_pre_key_serialize(axolotl_buffer **buffer, const session_pre_key *pr record.id = pre_key->id; record.has_publickey = 1; - record.publickey.data = axolotl_buffer_data(public_buf); - record.publickey.len = axolotl_buffer_len(public_buf); + record.publickey.data = signal_buffer_data(public_buf); + record.publickey.len = signal_buffer_len(public_buf); record.has_privatekey = 1; - record.privatekey.data = axolotl_buffer_data(private_buf); - record.privatekey.len = axolotl_buffer_len(private_buf); + record.privatekey.data = signal_buffer_data(private_buf); + record.privatekey.len = signal_buffer_len(private_buf); len = textsecure__pre_key_record_structure__get_packed_size(&record); - result_buf = axolotl_buffer_alloc(len); + result_buf = signal_buffer_alloc(len); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); result_size = textsecure__pre_key_record_structure__pack(&record, data); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } complete: if(public_buf) { - axolotl_buffer_free(public_buf); + signal_buffer_free(public_buf); } if(private_buf) { - axolotl_buffer_free(private_buf); + signal_buffer_free(private_buf); } if(result >= 0) { *buffer = result_buf; @@ -125,7 +130,7 @@ complete: return result; } -int session_pre_key_deserialize(session_pre_key **pre_key, const uint8_t *data, size_t len, axolotl_context *global_context) +int session_pre_key_deserialize(session_pre_key **pre_key, const uint8_t *data, size_t len, signal_context *global_context) { int result = 0; Textsecure__PreKeyRecordStructure *record = 0; @@ -136,12 +141,12 @@ int session_pre_key_deserialize(session_pre_key **pre_key, const uint8_t *data, record = textsecure__pre_key_record_structure__unpack(0, len, data); if(!record) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } if(!record->has_id || !record->has_publickey || !record->has_privatekey) { - result = AX_ERR_INVALID_KEY; + result = SG_ERR_INVALID_KEY; goto complete; } @@ -170,13 +175,13 @@ complete: textsecure__pre_key_record_structure__free_unpacked(record, 0); } if(public_key) { - AXOLOTL_UNREF(public_key); + SIGNAL_UNREF(public_key); } if(private_key) { - AXOLOTL_UNREF(private_key); + SIGNAL_UNREF(private_key); } if(key_pair) { - AXOLOTL_UNREF(key_pair); + SIGNAL_UNREF(key_pair); } if(result >= 0) { *pre_key = result_pre_key; @@ -194,12 +199,12 @@ ec_key_pair *session_pre_key_get_key_pair(const session_pre_key *pre_key) return pre_key->key_pair; } -void session_pre_key_destroy(axolotl_type_base *type) +void session_pre_key_destroy(signal_type_base *type) { session_pre_key *pre_key = (session_pre_key *)type; if(pre_key->key_pair) { - AXOLOTL_UNREF(pre_key->key_pair); + SIGNAL_UNREF(pre_key->key_pair); } free(pre_key); @@ -218,20 +223,20 @@ int session_signed_pre_key_create(session_signed_pre_key **pre_key, assert(signature_len > 0); if(signature_len > (SIZE_MAX - sizeof(session_signed_pre_key)) / sizeof(uint8_t)) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } result = malloc(sizeof(session_signed_pre_key) + (sizeof(uint8_t) * signature_len)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result, 0, sizeof(session_signed_pre_key)); - AXOLOTL_INIT(result, session_signed_pre_key_destroy); + SIGNAL_INIT(result, session_signed_pre_key_destroy); result->id = id; result->timestamp = timestamp; - AXOLOTL_REF(key_pair); + SIGNAL_REF(key_pair); result->key_pair = key_pair; result->signature_len = signature_len; @@ -242,15 +247,15 @@ int session_signed_pre_key_create(session_signed_pre_key **pre_key, return 0; } -int session_signed_pre_key_serialize(axolotl_buffer **buffer, const session_signed_pre_key *pre_key) +int session_signed_pre_key_serialize(signal_buffer **buffer, const session_signed_pre_key *pre_key) { int result = 0; size_t result_size = 0; Textsecure__SignedPreKeyRecordStructure record = TEXTSECURE__SIGNED_PRE_KEY_RECORD_STRUCTURE__INIT; - axolotl_buffer *public_buf = 0; - axolotl_buffer *private_buf = 0; - axolotl_buffer *signature_buf = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *public_buf = 0; + signal_buffer *private_buf = 0; + signal_buffer *signature_buf = 0; + signal_buffer *result_buf = 0; ec_public_key *public_key = 0; ec_private_key *private_key = 0; size_t len = 0; @@ -268,9 +273,9 @@ int session_signed_pre_key_serialize(axolotl_buffer **buffer, const session_sign goto complete; } - signature_buf = axolotl_buffer_create(pre_key->signature, pre_key->signature_len); + signature_buf = signal_buffer_create(pre_key->signature, pre_key->signature_len); if(!signature_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -281,43 +286,43 @@ int session_signed_pre_key_serialize(axolotl_buffer **buffer, const session_sign record.timestamp = pre_key->timestamp; record.has_publickey = 1; - record.publickey.data = axolotl_buffer_data(public_buf); - record.publickey.len = axolotl_buffer_len(public_buf); + record.publickey.data = signal_buffer_data(public_buf); + record.publickey.len = signal_buffer_len(public_buf); record.has_privatekey = 1; - record.privatekey.data = axolotl_buffer_data(private_buf); - record.privatekey.len = axolotl_buffer_len(private_buf); + record.privatekey.data = signal_buffer_data(private_buf); + record.privatekey.len = signal_buffer_len(private_buf); record.has_signature = 1; - record.signature.data = axolotl_buffer_data(signature_buf); - record.signature.len = axolotl_buffer_len(signature_buf); + record.signature.data = signal_buffer_data(signature_buf); + record.signature.len = signal_buffer_len(signature_buf); len = textsecure__signed_pre_key_record_structure__get_packed_size(&record); - result_buf = axolotl_buffer_alloc(len); + result_buf = signal_buffer_alloc(len); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); result_size = textsecure__signed_pre_key_record_structure__pack(&record, data); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } complete: if(public_buf) { - axolotl_buffer_free(public_buf); + signal_buffer_free(public_buf); } if(private_buf) { - axolotl_buffer_free(private_buf); + signal_buffer_free(private_buf); } if(signature_buf) { - axolotl_buffer_free(signature_buf); + signal_buffer_free(signature_buf); } if(result >= 0) { *buffer = result_buf; @@ -325,7 +330,7 @@ complete: return result; } -int session_signed_pre_key_deserialize(session_signed_pre_key **pre_key, const uint8_t *data, size_t len, axolotl_context *global_context) +int session_signed_pre_key_deserialize(session_signed_pre_key **pre_key, const uint8_t *data, size_t len, signal_context *global_context) { int result = 0; Textsecure__SignedPreKeyRecordStructure *record = 0; @@ -336,14 +341,14 @@ int session_signed_pre_key_deserialize(session_signed_pre_key **pre_key, const u record = textsecure__signed_pre_key_record_structure__unpack(0, len, data); if(!record) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } if(!record->has_id || !record->has_timestamp || !record->has_publickey || !record->has_privatekey || !record->has_signature) { - result = AX_ERR_INVALID_KEY; + result = SG_ERR_INVALID_KEY; goto complete; } @@ -374,13 +379,13 @@ complete: textsecure__signed_pre_key_record_structure__free_unpacked(record, 0); } if(public_key) { - AXOLOTL_UNREF(public_key); + SIGNAL_UNREF(public_key); } if(private_key) { - AXOLOTL_UNREF(private_key); + SIGNAL_UNREF(private_key); } if(key_pair) { - AXOLOTL_UNREF(key_pair); + SIGNAL_UNREF(key_pair); } if(result >= 0) { *pre_key = result_pre_key; @@ -413,12 +418,12 @@ size_t session_signed_pre_key_get_signature_len(const session_signed_pre_key *pr return pre_key->signature_len; } -void session_signed_pre_key_destroy(axolotl_type_base *type) +void session_signed_pre_key_destroy(signal_type_base *type) { session_signed_pre_key *pre_key = (session_signed_pre_key *)type; if(pre_key->key_pair) { - AXOLOTL_UNREF(pre_key->key_pair); + SIGNAL_UNREF(pre_key->key_pair); } free(pre_key); @@ -438,36 +443,36 @@ int session_pre_key_bundle_create(session_pre_key_bundle **bundle, result_bundle = malloc(sizeof(session_pre_key_bundle)); if(!result_bundle) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } memset(result_bundle, 0, sizeof(session_pre_key_bundle)); - AXOLOTL_INIT(result_bundle, session_pre_key_bundle_destroy); + SIGNAL_INIT(result_bundle, session_pre_key_bundle_destroy); result_bundle->registration_id = registration_id; result_bundle->device_id = device_id; result_bundle->pre_key_id = pre_key_id; if(pre_key_public) { - AXOLOTL_REF(pre_key_public); + SIGNAL_REF(pre_key_public); result_bundle->pre_key_public = pre_key_public; } result_bundle->signed_pre_key_id = signed_pre_key_id; if(signed_pre_key_public) { - AXOLOTL_REF(signed_pre_key_public); + SIGNAL_REF(signed_pre_key_public); result_bundle->signed_pre_key_public = signed_pre_key_public; } if(signed_pre_key_signature_data && signed_pre_key_signature_len > 0) { - result_bundle->signed_pre_key_signature = axolotl_buffer_create( + result_bundle->signed_pre_key_signature = signal_buffer_create( signed_pre_key_signature_data, signed_pre_key_signature_len); } if(identity_key) { - AXOLOTL_REF(identity_key); + SIGNAL_REF(identity_key); result_bundle->identity_key = identity_key; } @@ -477,7 +482,7 @@ complete: } else { if(result_bundle) { - AXOLOTL_UNREF(result_bundle); + SIGNAL_UNREF(result_bundle); } } return result; @@ -519,7 +524,7 @@ ec_public_key *session_pre_key_bundle_get_signed_pre_key(const session_pre_key_b return bundle->signed_pre_key_public; } -axolotl_buffer *session_pre_key_bundle_get_signed_pre_key_signature(const session_pre_key_bundle *bundle) +signal_buffer *session_pre_key_bundle_get_signed_pre_key_signature(const session_pre_key_bundle *bundle) { assert(bundle); return bundle->signed_pre_key_signature; @@ -531,21 +536,21 @@ ec_public_key *session_pre_key_bundle_get_identity_key(const session_pre_key_bun return bundle->identity_key; } -void session_pre_key_bundle_destroy(axolotl_type_base *type) +void session_pre_key_bundle_destroy(signal_type_base *type) { session_pre_key_bundle *bundle = (session_pre_key_bundle *)type; if(bundle->pre_key_public) { - AXOLOTL_UNREF(bundle->pre_key_public); + SIGNAL_UNREF(bundle->pre_key_public); } if(bundle->signed_pre_key_public) { - AXOLOTL_UNREF(bundle->signed_pre_key_public); + SIGNAL_UNREF(bundle->signed_pre_key_public); } if(bundle->signed_pre_key_signature) { - axolotl_buffer_free(bundle->signed_pre_key_signature); + signal_buffer_free(bundle->signed_pre_key_signature); } if(bundle->identity_key) { - AXOLOTL_UNREF(bundle->identity_key); + SIGNAL_UNREF(bundle->identity_key); } free(bundle); diff --git a/libs/libaxolotl/src/session_pre_key.h b/libs/libaxolotl/src/session_pre_key.h index 4b5f1b179a..ff8a9a8de2 100644 --- a/libs/libaxolotl/src/session_pre_key.h +++ b/libs/libaxolotl/src/session_pre_key.h @@ -3,7 +3,7 @@ #include <stdint.h> #include <stddef.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { @@ -14,21 +14,21 @@ extern "C" { /*------------------------------------------------------------------------*/ int session_pre_key_create(session_pre_key **pre_key, uint32_t id, ec_key_pair *key_pair); -int session_pre_key_serialize(axolotl_buffer **buffer, const session_pre_key *pre_key); -int session_pre_key_deserialize(session_pre_key **pre_key, const uint8_t *data, size_t len, axolotl_context *global_context); +int session_pre_key_serialize(signal_buffer **buffer, const session_pre_key *pre_key); +int session_pre_key_deserialize(session_pre_key **pre_key, const uint8_t *data, size_t len, signal_context *global_context); uint32_t session_pre_key_get_id(const session_pre_key *pre_key); ec_key_pair *session_pre_key_get_key_pair(const session_pre_key *pre_key); -void session_pre_key_destroy(axolotl_type_base *type); +void session_pre_key_destroy(signal_type_base *type); /*------------------------------------------------------------------------*/ int session_signed_pre_key_create(session_signed_pre_key **pre_key, uint32_t id, uint64_t timestamp, ec_key_pair *key_pair, const uint8_t *signature, size_t signature_len); -int session_signed_pre_key_serialize(axolotl_buffer **buffer, const session_signed_pre_key *pre_key); -int session_signed_pre_key_deserialize(session_signed_pre_key **pre_key, const uint8_t *data, size_t len, axolotl_context *global_context); +int session_signed_pre_key_serialize(signal_buffer **buffer, const session_signed_pre_key *pre_key); +int session_signed_pre_key_deserialize(session_signed_pre_key **pre_key, const uint8_t *data, size_t len, signal_context *global_context); uint32_t session_signed_pre_key_get_id(const session_signed_pre_key *pre_key); uint64_t session_signed_pre_key_get_timestamp(const session_signed_pre_key *pre_key); @@ -36,7 +36,7 @@ ec_key_pair *session_signed_pre_key_get_key_pair(const session_signed_pre_key *p const uint8_t *session_signed_pre_key_get_signature(const session_signed_pre_key *pre_key); size_t session_signed_pre_key_get_signature_len(const session_signed_pre_key *pre_key); -void session_signed_pre_key_destroy(axolotl_type_base *type); +void session_signed_pre_key_destroy(signal_type_base *type); /*------------------------------------------------------------------------*/ @@ -53,10 +53,10 @@ uint32_t session_pre_key_bundle_get_pre_key_id(const session_pre_key_bundle *bun ec_public_key *session_pre_key_bundle_get_pre_key(const session_pre_key_bundle *bundle); uint32_t session_pre_key_bundle_get_signed_pre_key_id(const session_pre_key_bundle *bundle); ec_public_key *session_pre_key_bundle_get_signed_pre_key(const session_pre_key_bundle *bundle); -axolotl_buffer *session_pre_key_bundle_get_signed_pre_key_signature(const session_pre_key_bundle *bundle); +signal_buffer *session_pre_key_bundle_get_signed_pre_key_signature(const session_pre_key_bundle *bundle); ec_public_key *session_pre_key_bundle_get_identity_key(const session_pre_key_bundle *bundle); -void session_pre_key_bundle_destroy(axolotl_type_base *type); +void session_pre_key_bundle_destroy(signal_type_base *type); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/session_record.c b/libs/libaxolotl/src/session_record.c index c6b5cba5a4..0f72e90f83 100644 --- a/libs/libaxolotl/src/session_record.c +++ b/libs/libaxolotl/src/session_record.c @@ -4,10 +4,10 @@ #include <string.h> #include <assert.h> -#include "axolotl_internal.h" #include "session_state.h" #include "utlist.h" #include "LocalStorageProtocol.pb-c.h" +#include "signal_protocol_internal.h" #define ARCHIVED_STATES_MAX_LENGTH 40 @@ -19,34 +19,34 @@ struct session_record_state_node struct session_record { - axolotl_type_base base; + signal_type_base base; session_state *state; session_record_state_node *previous_states_head; int is_fresh; - axolotl_context *global_context; + signal_context *global_context; }; static void session_record_free_previous_states(session_record *record); -int session_record_create(session_record **record, session_state *state, axolotl_context *global_context) +int session_record_create(session_record **record, session_state *state, signal_context *global_context) { session_record *result = malloc(sizeof(session_record)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result, 0, sizeof(session_record)); - AXOLOTL_INIT(result, session_record_destroy); + SIGNAL_INIT(result, session_record_destroy); if(!state) { int ret = session_state_create(&result->state, global_context); if(ret < 0) { - AXOLOTL_UNREF(result); + SIGNAL_UNREF(result); return ret; } result->is_fresh = 1; } else { - AXOLOTL_REF(state); + SIGNAL_REF(state); result->state = state; result->is_fresh = 0; } @@ -56,21 +56,26 @@ int session_record_create(session_record **record, session_state *state, axolotl return 0; } -int session_record_serialize(axolotl_buffer **buffer, const session_record *record) +int session_record_serialize(signal_buffer **buffer, const session_record *record) { int result = 0; size_t result_size = 0; unsigned int i = 0; Textsecure__RecordStructure record_structure = TEXTSECURE__RECORD_STRUCTURE__INIT; session_record_state_node *cur_node = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; size_t len = 0; uint8_t *data = 0; + if(!record) { + result = SG_ERR_INVAL; + goto complete; + } + if(record->state) { record_structure.currentsession = malloc(sizeof(Textsecure__SessionStructure)); if(!record_structure.currentsession) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } textsecure__session_structure__init(record_structure.currentsession); @@ -81,17 +86,17 @@ int session_record_serialize(axolotl_buffer **buffer, const session_record *reco } if(record->previous_states_head) { - unsigned int count; + size_t count; DL_COUNT(record->previous_states_head, cur_node, count); if(count > SIZE_MAX / sizeof(Textsecure__SessionStructure *)) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } record_structure.previoussessions = malloc(sizeof(Textsecure__SessionStructure *) * count); if(!record_structure.previoussessions) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -99,7 +104,7 @@ int session_record_serialize(axolotl_buffer **buffer, const session_record *reco DL_FOREACH(record->previous_states_head, cur_node) { record_structure.previoussessions[i] = malloc(sizeof(Textsecure__SessionStructure)); if(!record_structure.previoussessions[i]) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; break; } textsecure__session_structure__init(record_structure.previoussessions[i]); @@ -117,17 +122,17 @@ int session_record_serialize(axolotl_buffer **buffer, const session_record *reco len = textsecure__record_structure__get_packed_size(&record_structure); - result_buf = axolotl_buffer_alloc(len); + result_buf = signal_buffer_alloc(len); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); result_size = textsecure__record_structure__pack(&record_structure, data); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } @@ -151,7 +156,7 @@ complete: return result; } -int session_record_deserialize(session_record **record, const uint8_t *data, size_t len, axolotl_context *global_context) +int session_record_deserialize(session_record **record, const uint8_t *data, size_t len, signal_context *global_context) { int result = 0; session_record *result_record = 0; @@ -161,7 +166,7 @@ int session_record_deserialize(session_record **record, const uint8_t *data, siz record_structure = textsecure__record_structure__unpack(0, len, data); if(!record_structure) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } @@ -176,7 +181,7 @@ int session_record_deserialize(session_record **record, const uint8_t *data, siz if(result < 0) { goto complete; } - AXOLOTL_UNREF(current_state); + SIGNAL_UNREF(current_state); current_state = 0; result_record->is_fresh = 0; @@ -188,7 +193,7 @@ int session_record_deserialize(session_record **record, const uint8_t *data, siz session_record_state_node *node = malloc(sizeof(session_record_state_node)); if(!node) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } @@ -209,7 +214,7 @@ complete: textsecure__record_structure__free_unpacked(record_structure, 0); } if(current_state) { - AXOLOTL_UNREF(current_state); + SIGNAL_UNREF(current_state); } if(previous_states_head) { session_record_state_node *cur_node; @@ -221,7 +226,7 @@ complete: } if(result_record) { if(result < 0) { - AXOLOTL_UNREF(result_record); + SIGNAL_UNREF(result_record); } else { *record = result_record; @@ -231,10 +236,10 @@ complete: return result; } -int session_record_copy(session_record **record, session_record *other_record, axolotl_context *global_context) +int session_record_copy(session_record **record, session_record *other_record, signal_context *global_context) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; size_t len = 0; uint8_t *data = 0; @@ -246,8 +251,8 @@ int session_record_copy(session_record **record, session_record *other_record, a goto complete; } - data = axolotl_buffer_data(buffer); - len = axolotl_buffer_len(buffer); + data = signal_buffer_data(buffer); + len = signal_buffer_len(buffer); result = session_record_deserialize(record, data, len, global_context); if(result < 0) { @@ -256,7 +261,7 @@ int session_record_copy(session_record **record, session_record *other_record, a complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } return result; } @@ -297,9 +302,9 @@ void session_record_set_state(session_record *record, session_state *state) assert(record); assert(state); if(record->state) { - AXOLOTL_UNREF(record->state); + SIGNAL_UNREF(record->state); } - AXOLOTL_REF(state); + SIGNAL_REF(state); record->state = state; } @@ -330,7 +335,7 @@ session_record_state_node *session_record_get_previous_states_remove(session_rec next_node = node->next; DL_DELETE(record->previous_states_head, node); - AXOLOTL_UNREF(node->state); + SIGNAL_UNREF(node->state); free(node); return next_node; } @@ -356,7 +361,7 @@ int session_record_archive_current_state(session_record *record) result = session_record_promote_state(record, new_state); complete: - AXOLOTL_UNREF(new_state); + SIGNAL_UNREF(new_state); return result; } @@ -373,7 +378,7 @@ int session_record_promote_state(session_record *record, session_state *promoted if(record->state) { session_record_state_node *node = malloc(sizeof(session_record_state_node)); if(!node) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } node->state = record->state; @@ -382,7 +387,7 @@ int session_record_promote_state(session_record *record, session_state *promoted } // Make the promoted state the current state - AXOLOTL_REF(promoted_state); + SIGNAL_REF(promoted_state); record->state = promoted_state; // Remove any previous nodes beyond the maximum length @@ -391,7 +396,7 @@ int session_record_promote_state(session_record *record, session_state *promoted if(count > ARCHIVED_STATES_MAX_LENGTH) { DL_DELETE(record->previous_states_head, cur_node); if(cur_node->state) { - AXOLOTL_UNREF(cur_node->state); + SIGNAL_UNREF(cur_node->state); } free(cur_node); } @@ -407,19 +412,19 @@ static void session_record_free_previous_states(session_record *record) DL_FOREACH_SAFE(record->previous_states_head, cur_node, tmp_node) { DL_DELETE(record->previous_states_head, cur_node); if(cur_node->state) { - AXOLOTL_UNREF(cur_node->state); + SIGNAL_UNREF(cur_node->state); } free(cur_node); } record->previous_states_head = 0; } -void session_record_destroy(axolotl_type_base *type) +void session_record_destroy(signal_type_base *type) { session_record *record = (session_record *)type; if(record->state) { - AXOLOTL_UNREF(record->state); + SIGNAL_UNREF(record->state); } session_record_free_previous_states(record); diff --git a/libs/libaxolotl/src/session_record.h b/libs/libaxolotl/src/session_record.h index 99f113d2eb..581e232640 100644 --- a/libs/libaxolotl/src/session_record.h +++ b/libs/libaxolotl/src/session_record.h @@ -3,16 +3,16 @@ #include <stdint.h> #include <stddef.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { #endif -int session_record_create(session_record **record, session_state *state, axolotl_context *global_context); -int session_record_serialize(axolotl_buffer **buffer, const session_record *record); -int session_record_deserialize(session_record **record, const uint8_t *data, size_t len, axolotl_context *global_context); -int session_record_copy(session_record **record, session_record *other_record, axolotl_context *global_context); +int session_record_create(session_record **record, session_state *state, signal_context *global_context); +int session_record_serialize(signal_buffer **buffer, const session_record *record); +int session_record_deserialize(session_record **record, const uint8_t *data, size_t len, signal_context *global_context); +int session_record_copy(session_record **record, session_record *other_record, signal_context *global_context); int session_record_has_session_state(session_record *record, uint32_t version, const ec_public_key *alice_base_key); session_state *session_record_get_state(session_record *record); @@ -41,7 +41,7 @@ int session_record_archive_current_state(session_record *record); int session_record_promote_state(session_record *record, session_state *promoted_state); -void session_record_destroy(axolotl_type_base *type); +void session_record_destroy(signal_type_base *type); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/session_state.c b/libs/libaxolotl/src/session_state.c index db787ebf72..94cf9d3014 100644 --- a/libs/libaxolotl/src/session_state.c +++ b/libs/libaxolotl/src/session_state.c @@ -7,8 +7,8 @@ #include "hkdf.h" #include "curve.h" #include "ratchet.h" -#include "axolotl_internal.h" #include "LocalStorageProtocol.pb-c.h" +#include "signal_protocol_internal.h" #include "utlist.h" @@ -53,7 +53,7 @@ typedef struct session_pending_pre_key struct session_state { - axolotl_type_base base; + signal_type_base base; uint32_t session_version; ec_public_key *local_identity_public; @@ -79,7 +79,7 @@ struct session_state int needs_refresh; ec_public_key *alice_base_key; - axolotl_context *global_context; + signal_context *global_context; }; static int session_state_serialize_prepare_sender_chain( @@ -115,35 +115,35 @@ static void session_state_serialize_prepare_pending_pre_key_free( static int session_state_deserialize_protobuf_pending_key_exchange( session_pending_key_exchange *result_exchange, Textsecure__SessionStructure__PendingKeyExchange *exchange_structure, - axolotl_context *global_context); + signal_context *global_context); static int session_state_deserialize_protobuf_pending_pre_key( session_pending_pre_key *result_pre_key, Textsecure__SessionStructure__PendingPreKey *pre_key_structure, - axolotl_context *global_context); + signal_context *global_context); static int session_state_deserialize_protobuf_sender_chain( uint32_t session_version, session_state_sender_chain *chain, Textsecure__SessionStructure__Chain *chain_structure, - axolotl_context *global_context); + signal_context *global_context); static int session_state_deserialize_protobuf_receiver_chain( uint32_t session_version, session_state_receiver_chain *chain, Textsecure__SessionStructure__Chain *chain_structure, - axolotl_context *global_context); + signal_context *global_context); static void session_state_free_sender_chain(session_state *state); static void session_state_free_receiver_chain_node(session_state_receiver_chain *node); static void session_state_free_receiver_chain(session_state *state); static session_state_receiver_chain *session_state_find_receiver_chain(const session_state *state, const ec_public_key *sender_ephemeral); -int session_state_create(session_state **state, axolotl_context *global_context) +int session_state_create(session_state **state, signal_context *global_context) { session_state *result = malloc(sizeof(session_state)); if(!result) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(result, 0, sizeof(session_state)); - AXOLOTL_INIT(result, session_state_destroy); + SIGNAL_INIT(result, session_state_destroy); result->session_version = 2; result->global_context = global_context; @@ -151,18 +151,18 @@ int session_state_create(session_state **state, axolotl_context *global_context) return 0; } -int session_state_serialize(axolotl_buffer **buffer, session_state *state) +int session_state_serialize(signal_buffer **buffer, session_state *state) { int result = 0; size_t result_size = 0; Textsecure__SessionStructure *state_structure = 0; - axolotl_buffer *result_buf = 0; + signal_buffer *result_buf = 0; size_t len = 0; uint8_t *data = 0; state_structure = malloc(sizeof(Textsecure__SessionStructure)); if(!state_structure) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } textsecure__session_structure__init(state_structure); @@ -174,17 +174,17 @@ int session_state_serialize(axolotl_buffer **buffer, session_state *state) len = textsecure__session_structure__get_packed_size(state_structure); - result_buf = axolotl_buffer_alloc(len); + result_buf = signal_buffer_alloc(len); if(!result_buf) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } - data = axolotl_buffer_data(result_buf); + data = signal_buffer_data(result_buf); result_size = textsecure__session_structure__pack(state_structure, data); if(result_size != len) { - axolotl_buffer_free(result_buf); - result = AX_ERR_INVALID_PROTO_BUF; + signal_buffer_free(result_buf); + result = SG_ERR_INVALID_PROTO_BUF; result_buf = 0; goto complete; } @@ -199,7 +199,7 @@ complete: return result; } -int session_state_deserialize(session_state **state, const uint8_t *data, size_t len, axolotl_context *global_context) +int session_state_deserialize(session_state **state, const uint8_t *data, size_t len, signal_context *global_context) { int result = 0; session_state *result_state = 0; @@ -207,7 +207,7 @@ int session_state_deserialize(session_state **state, const uint8_t *data, size_t session_structure = textsecure__session_structure__unpack(0, len, data); if(!session_structure) { - result = AX_ERR_INVALID_PROTO_BUF; + result = SG_ERR_INVALID_PROTO_BUF; goto complete; } @@ -222,7 +222,7 @@ complete: } if(result_state) { if(result < 0) { - AXOLOTL_UNREF(result_state); + SIGNAL_UNREF(result_state); } else { *state = result_state; @@ -275,7 +275,7 @@ int session_state_serialize_prepare(session_state *state, Textsecure__SessionStr if(state->has_sender_chain) { session_structure->senderchain = malloc(sizeof(Textsecure__SessionStructure__Chain)); if(!session_structure->senderchain) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } textsecure__session_structure__chain__init(session_structure->senderchain); @@ -287,27 +287,25 @@ int session_state_serialize_prepare(session_state *state, Textsecure__SessionStr } if(state->receiver_chain_head) { - size_t i = 0; - - unsigned int count; + size_t count, i = 0; session_state_receiver_chain *cur_node; DL_COUNT(state->receiver_chain_head, cur_node, count); if(count > SIZE_MAX / sizeof(Textsecure__SessionStructure__Chain *)) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } session_structure->receiverchains = malloc(sizeof(Textsecure__SessionStructure__Chain *) * count); if(!session_structure->receiverchains) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } DL_FOREACH(state->receiver_chain_head, cur_node) { session_structure->receiverchains[i] = malloc(sizeof(Textsecure__SessionStructure__Chain)); if(!session_structure->receiverchains[i]) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; break; } textsecure__session_structure__chain__init(session_structure->receiverchains[i]); @@ -326,7 +324,7 @@ int session_state_serialize_prepare(session_state *state, Textsecure__SessionStr if(state->has_pending_key_exchange) { session_structure->pendingkeyexchange = malloc(sizeof(Textsecure__SessionStructure__PendingKeyExchange)); if(!session_structure->pendingkeyexchange) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } textsecure__session_structure__pending_key_exchange__init(session_structure->pendingkeyexchange); @@ -341,7 +339,7 @@ int session_state_serialize_prepare(session_state *state, Textsecure__SessionStr if(state->has_pending_pre_key) { session_structure->pendingprekey = malloc(sizeof(Textsecure__SessionStructure__PendingPreKey)); if(!session_structure->pendingprekey) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } textsecure__session_structure__pending_pre_key__init(session_structure->pendingprekey); @@ -457,7 +455,7 @@ static int session_state_serialize_prepare_chain_chain_key( int result = 0; chain_structure->chainkey = malloc(sizeof(Textsecure__SessionStructure__Chain__ChainKey)); if(!chain_structure->chainkey) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } textsecure__session_structure__chain__chain_key__init(chain_structure->chainkey); @@ -480,9 +478,7 @@ static int session_state_serialize_prepare_chain_message_keys_list( Textsecure__SessionStructure__Chain *chain_structure) { int result = 0; - size_t i = 0; - - unsigned int count; + size_t count, i = 0; message_keys_node *cur_node; DL_COUNT(message_keys_head, cur_node, count); @@ -491,20 +487,20 @@ static int session_state_serialize_prepare_chain_message_keys_list( } if(count > SIZE_MAX / sizeof(Textsecure__SessionStructure__Chain__MessageKey *)) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } chain_structure->messagekeys = malloc(sizeof(Textsecure__SessionStructure__Chain__MessageKey *) * count); if(!chain_structure->messagekeys) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } DL_FOREACH(message_keys_head, cur_node) { chain_structure->messagekeys[i] = malloc(sizeof(Textsecure__SessionStructure__Chain__MessageKey)); if(!chain_structure->messagekeys[i]) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; break; } textsecure__session_structure__chain__message_key__init(chain_structure->messagekeys[i]); @@ -535,7 +531,7 @@ static int session_state_serialize_prepare_message_keys( message_key_structure->cipherkey.data = malloc(sizeof(message_key->cipher_key)); if(!message_key_structure->cipherkey.data) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } memcpy(message_key_structure->cipherkey.data, message_key->cipher_key, sizeof(message_key->cipher_key)); @@ -544,7 +540,7 @@ static int session_state_serialize_prepare_message_keys( message_key_structure->mackey.data = malloc(sizeof(message_key->mac_key)); if(!message_key_structure->mackey.data) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } memcpy(message_key_structure->mackey.data, message_key->mac_key, sizeof(message_key->mac_key)); @@ -553,7 +549,7 @@ static int session_state_serialize_prepare_message_keys( message_key_structure->iv.data = malloc(sizeof(message_key->iv)); if(!message_key_structure->iv.data) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } memcpy(message_key_structure->iv.data, message_key->iv, sizeof(message_key->iv)); @@ -781,7 +777,7 @@ static void session_state_serialize_prepare_pending_pre_key_free( free(pre_key_structure); } -int session_state_deserialize_protobuf(session_state **state, Textsecure__SessionStructure *session_structure, axolotl_context *global_context) +int session_state_deserialize_protobuf(session_state **state, Textsecure__SessionStructure *session_structure, signal_context *global_context) { int result = 0; session_state *result_state = 0; @@ -828,7 +824,7 @@ int session_state_deserialize_protobuf(session_state **state, Textsecure__Sessio &result_state->root_key, kdf, session_structure->rootkey.data, session_structure->rootkey.len, global_context); - AXOLOTL_UNREF(kdf); + SIGNAL_UNREF(kdf); if(result < 0) { goto complete; } @@ -854,7 +850,7 @@ int session_state_deserialize_protobuf(session_state **state, Textsecure__Sessio for(i = 0; i < session_structure->n_receiverchains; i++) { session_state_receiver_chain *node = malloc(sizeof(session_state_receiver_chain)); if(!node) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } memset(node, 0, sizeof(session_state_receiver_chain)); @@ -921,7 +917,7 @@ complete: } else { if(result_state) { - AXOLOTL_UNREF(result_state); + SIGNAL_UNREF(result_state); } } return result; @@ -930,7 +926,7 @@ complete: static int session_state_deserialize_protobuf_pending_key_exchange( session_pending_key_exchange *result_exchange, Textsecure__SessionStructure__PendingKeyExchange *exchange_structure, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; @@ -1025,17 +1021,17 @@ static int session_state_deserialize_protobuf_pending_key_exchange( result_exchange->local_identity_key = local_identity_key; complete: - AXOLOTL_UNREF(local_base_key_public); - AXOLOTL_UNREF(local_base_key_private); - AXOLOTL_UNREF(local_ratchet_key_public); - AXOLOTL_UNREF(local_ratchet_key_private); - AXOLOTL_UNREF(local_identity_key_public); - AXOLOTL_UNREF(local_identity_key_private); + SIGNAL_UNREF(local_base_key_public); + SIGNAL_UNREF(local_base_key_private); + SIGNAL_UNREF(local_ratchet_key_public); + SIGNAL_UNREF(local_ratchet_key_private); + SIGNAL_UNREF(local_identity_key_public); + SIGNAL_UNREF(local_identity_key_private); if(result < 0) { - AXOLOTL_UNREF(local_base_key); - AXOLOTL_UNREF(local_ratchet_key); - AXOLOTL_UNREF(local_identity_key); + SIGNAL_UNREF(local_base_key); + SIGNAL_UNREF(local_ratchet_key); + SIGNAL_UNREF(local_identity_key); } return result; @@ -1044,7 +1040,7 @@ complete: static int session_state_deserialize_protobuf_pending_pre_key( session_pending_pre_key *result_pre_key, Textsecure__SessionStructure__PendingPreKey *pre_key_structure, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; @@ -1077,7 +1073,7 @@ static int session_state_deserialize_protobuf_sender_chain( uint32_t session_version, session_state_sender_chain *chain, Textsecure__SessionStructure__Chain *chain_structure, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; hkdf_context *kdf = 0; @@ -1131,12 +1127,12 @@ static int session_state_deserialize_protobuf_sender_chain( chain->chain_key = sender_chain_key; complete: - AXOLOTL_UNREF(kdf); - AXOLOTL_UNREF(sender_ratchet_key_public); - AXOLOTL_UNREF(sender_ratchet_key_private); + SIGNAL_UNREF(kdf); + SIGNAL_UNREF(sender_ratchet_key_public); + SIGNAL_UNREF(sender_ratchet_key_private); if(result < 0) { - AXOLOTL_UNREF(sender_ratchet_key_pair); - AXOLOTL_UNREF(sender_chain_key); + SIGNAL_UNREF(sender_ratchet_key_pair); + SIGNAL_UNREF(sender_chain_key); } return result; } @@ -1145,7 +1141,7 @@ static int session_state_deserialize_protobuf_receiver_chain( uint32_t session_version, session_state_receiver_chain *chain, Textsecure__SessionStructure__Chain *chain_structure, - axolotl_context *global_context) + signal_context *global_context) { int result = 0; @@ -1189,7 +1185,7 @@ static int session_state_deserialize_protobuf_receiver_chain( message_keys_node *node = malloc(sizeof(message_keys_node)); if(!node) { - result = AX_ERR_NOMEM; + result = SG_ERR_NOMEM; goto complete; } memset(node, 0, sizeof(message_keys_node)); @@ -1216,16 +1212,16 @@ static int session_state_deserialize_protobuf_receiver_chain( chain->message_keys_head = message_keys_head; complete: - AXOLOTL_UNREF(kdf); + SIGNAL_UNREF(kdf); if(result < 0) { - AXOLOTL_UNREF(sender_ratchet_key); - AXOLOTL_UNREF(chain_key); + SIGNAL_UNREF(sender_ratchet_key); + SIGNAL_UNREF(chain_key); if(message_keys_head) { message_keys_node *cur_node; message_keys_node *tmp_node; DL_FOREACH_SAFE(message_keys_head, cur_node, tmp_node) { DL_DELETE(message_keys_head, cur_node); - axolotl_explicit_bzero(&cur_node->message_key, sizeof(ratchet_message_keys)); + signal_explicit_bzero(&cur_node->message_key, sizeof(ratchet_message_keys)); free(cur_node); } } @@ -1233,10 +1229,10 @@ complete: return result; } -int session_state_copy(session_state **state, session_state *other_state, axolotl_context *global_context) +int session_state_copy(session_state **state, session_state *other_state, signal_context *global_context) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; size_t len = 0; uint8_t *data = 0; @@ -1248,8 +1244,8 @@ int session_state_copy(session_state **state, session_state *other_state, axolot goto complete; } - data = axolotl_buffer_data(buffer); - len = axolotl_buffer_len(buffer); + data = signal_buffer_data(buffer); + len = signal_buffer_len(buffer); result = session_state_deserialize(state, data, len, global_context); if(result < 0) { @@ -1258,7 +1254,7 @@ int session_state_copy(session_state **state, session_state *other_state, axolot complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } return result; } @@ -1280,9 +1276,9 @@ void session_state_set_local_identity_key(session_state *state, ec_public_key *i assert(state); assert(identity_key); if(state->local_identity_public) { - AXOLOTL_UNREF(state->local_identity_public); + SIGNAL_UNREF(state->local_identity_public); } - AXOLOTL_REF(identity_key); + SIGNAL_REF(identity_key); state->local_identity_public = identity_key; } @@ -1297,9 +1293,9 @@ void session_state_set_remote_identity_key(session_state *state, ec_public_key * assert(state); assert(identity_key); if(state->remote_identity_public) { - AXOLOTL_UNREF(state->remote_identity_public); + SIGNAL_UNREF(state->remote_identity_public); } - AXOLOTL_REF(identity_key); + SIGNAL_REF(identity_key); state->remote_identity_public = identity_key; } @@ -1314,9 +1310,9 @@ void session_state_set_root_key(session_state *state, ratchet_root_key *root_key assert(state); assert(root_key); if(state->root_key) { - AXOLOTL_UNREF(state->root_key); + SIGNAL_UNREF(state->root_key); } - AXOLOTL_REF(root_key); + SIGNAL_REF(root_key); state->root_key = root_key; } @@ -1347,15 +1343,15 @@ void session_state_set_sender_chain(session_state *state, ec_key_pair *sender_ra state->has_sender_chain = 1; if(state->sender_chain.sender_ratchet_key_pair) { - AXOLOTL_UNREF(state->sender_chain.sender_ratchet_key_pair); + SIGNAL_UNREF(state->sender_chain.sender_ratchet_key_pair); } - AXOLOTL_REF(sender_ratchet_key_pair); + SIGNAL_REF(sender_ratchet_key_pair); state->sender_chain.sender_ratchet_key_pair = sender_ratchet_key_pair; if(state->sender_chain.chain_key) { - AXOLOTL_UNREF(state->sender_chain.chain_key); + SIGNAL_UNREF(state->sender_chain.chain_key); } - AXOLOTL_REF(chain_key); + SIGNAL_REF(chain_key); state->sender_chain.chain_key = chain_key; } @@ -1387,14 +1383,14 @@ int session_state_set_sender_chain_key(session_state *state, ratchet_chain_key * assert(state); if(state->has_sender_chain) { if(state->sender_chain.chain_key) { - AXOLOTL_UNREF(state->sender_chain.chain_key); + SIGNAL_UNREF(state->sender_chain.chain_key); } - AXOLOTL_REF(chain_key); + SIGNAL_REF(chain_key); state->sender_chain.chain_key = chain_key; return 0; } else { - return AX_ERR_UNKNOWN; + return SG_ERR_UNKNOWN; } } @@ -1447,7 +1443,7 @@ int session_state_remove_message_keys(session_state *state, if(cur_node->message_key.counter == counter) { memcpy(message_keys_result, &(cur_node->message_key), sizeof(ratchet_message_keys)); DL_DELETE(chain->message_keys_head, cur_node); - axolotl_explicit_bzero(&cur_node->message_key, sizeof(ratchet_message_keys)); + signal_explicit_bzero(&cur_node->message_key, sizeof(ratchet_message_keys)); free(cur_node); return 1; } @@ -1474,7 +1470,7 @@ int session_state_set_message_keys(session_state *state, node = malloc(sizeof(message_keys_node)); if(!node) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memcpy(&(node->message_key), message_keys, sizeof(ratchet_message_keys)); node->prev = 0; @@ -1486,7 +1482,7 @@ int session_state_set_message_keys(session_state *state, while(count > MAX_MESSAGE_KEYS) { node = chain->message_keys_head; DL_DELETE(chain->message_keys_head, node); - axolotl_explicit_bzero(&node->message_key, sizeof(ratchet_message_keys)); + signal_explicit_bzero(&node->message_key, sizeof(ratchet_message_keys)); free(node); --count; } @@ -1505,13 +1501,13 @@ int session_state_add_receiver_chain(session_state *state, ec_public_key *sender node = malloc(sizeof(session_state_receiver_chain)); if(!node) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } memset(node, 0, sizeof(session_state_receiver_chain)); - AXOLOTL_REF(sender_ratchet_key); + SIGNAL_REF(sender_ratchet_key); node->sender_ratchet_key = sender_ratchet_key; - AXOLOTL_REF(chain_key); + SIGNAL_REF(chain_key); node->chain_key = chain_key; DL_APPEND(state->receiver_chain_head, node); @@ -1538,13 +1534,13 @@ int session_state_set_receiver_chain_key(session_state *state, ec_public_key *se node = session_state_find_receiver_chain(state, sender_ephemeral); if(!node) { - axolotl_log(state->global_context, AX_LOG_WARNING, "Couldn't find receiver chain to set chain key on"); - result = AX_ERR_UNKNOWN; + signal_log(state->global_context, SG_LOG_WARNING, "Couldn't find receiver chain to set chain key on"); + result = SG_ERR_UNKNOWN; goto complete; } - AXOLOTL_UNREF(node->chain_key); - AXOLOTL_REF(chain_key); + SIGNAL_UNREF(node->chain_key); + SIGNAL_REF(chain_key); node->chain_key = chain_key; complete: @@ -1589,21 +1585,21 @@ void session_state_set_pending_key_exchange(session_state *state, assert(our_identity_key); if(state->pending_key_exchange.local_base_key) { - AXOLOTL_UNREF(state->pending_key_exchange.local_base_key); + SIGNAL_UNREF(state->pending_key_exchange.local_base_key); state->pending_key_exchange.local_base_key = 0; } if(state->pending_key_exchange.local_ratchet_key) { - AXOLOTL_UNREF(state->pending_key_exchange.local_ratchet_key); + SIGNAL_UNREF(state->pending_key_exchange.local_ratchet_key); state->pending_key_exchange.local_ratchet_key = 0; } if(state->pending_key_exchange.local_identity_key) { - AXOLOTL_UNREF(state->pending_key_exchange.local_identity_key); + SIGNAL_UNREF(state->pending_key_exchange.local_identity_key); state->pending_key_exchange.local_identity_key = 0; } - AXOLOTL_REF(our_base_key); - AXOLOTL_REF(our_ratchet_key); - AXOLOTL_REF(our_identity_key); + SIGNAL_REF(our_base_key); + SIGNAL_REF(our_ratchet_key); + SIGNAL_REF(our_identity_key); state->has_pending_key_exchange = 1; state->pending_key_exchange.sequence = sequence; @@ -1669,11 +1665,11 @@ void session_state_set_unacknowledged_pre_key_message(session_state *state, assert(base_key); if(state->pending_pre_key.base_key) { - AXOLOTL_UNREF(state->pending_pre_key.base_key); + SIGNAL_UNREF(state->pending_pre_key.base_key); state->pending_pre_key.base_key = 0; } - AXOLOTL_REF(base_key); + SIGNAL_REF(base_key); state->has_pending_pre_key = 1; if(pre_key_id) { @@ -1723,7 +1719,7 @@ void session_state_clear_unacknowledged_pre_key_message(session_state *state) { assert(state); if(state->pending_pre_key.base_key) { - AXOLOTL_UNREF(state->pending_pre_key.base_key); + SIGNAL_UNREF(state->pending_pre_key.base_key); } memset(&state->pending_pre_key, 0, sizeof(state->pending_pre_key)); state->has_pending_pre_key = 0; @@ -1772,9 +1768,9 @@ void session_state_set_alice_base_key(session_state *state, ec_public_key *key) assert(key); if(state->alice_base_key) { - AXOLOTL_UNREF(state->alice_base_key); + SIGNAL_UNREF(state->alice_base_key); } - AXOLOTL_REF(key); + SIGNAL_REF(key); state->alice_base_key = key; } @@ -1787,11 +1783,11 @@ ec_public_key *session_state_get_alice_base_key(const session_state *state) static void session_state_free_sender_chain(session_state *state) { if(state->sender_chain.sender_ratchet_key_pair) { - AXOLOTL_UNREF(state->sender_chain.sender_ratchet_key_pair); + SIGNAL_UNREF(state->sender_chain.sender_ratchet_key_pair); state->sender_chain.sender_ratchet_key_pair = 0; } if(state->sender_chain.chain_key) { - AXOLOTL_UNREF(state->sender_chain.chain_key); + SIGNAL_UNREF(state->sender_chain.chain_key); state->sender_chain.chain_key = 0; } @@ -1800,7 +1796,7 @@ static void session_state_free_sender_chain(session_state *state) message_keys_node *tmp_node; DL_FOREACH_SAFE(state->sender_chain.message_keys_head, cur_node, tmp_node) { DL_DELETE(state->sender_chain.message_keys_head, cur_node); - axolotl_explicit_bzero(&cur_node->message_key, sizeof(ratchet_message_keys)); + signal_explicit_bzero(&cur_node->message_key, sizeof(ratchet_message_keys)); free(cur_node); } state->sender_chain.message_keys_head = 0; @@ -1810,10 +1806,10 @@ static void session_state_free_sender_chain(session_state *state) static void session_state_free_receiver_chain_node(session_state_receiver_chain *node) { if(node->sender_ratchet_key) { - AXOLOTL_UNREF(node->sender_ratchet_key); + SIGNAL_UNREF(node->sender_ratchet_key); } if(node->chain_key) { - AXOLOTL_UNREF(node->chain_key); + SIGNAL_UNREF(node->chain_key); } if(node->message_keys_head) { @@ -1821,7 +1817,7 @@ static void session_state_free_receiver_chain_node(session_state_receiver_chain message_keys_node *tmp_node; DL_FOREACH_SAFE(node->message_keys_head, cur_node, tmp_node) { DL_DELETE(node->message_keys_head, cur_node); - axolotl_explicit_bzero(&cur_node->message_key, sizeof(ratchet_message_keys)); + signal_explicit_bzero(&cur_node->message_key, sizeof(ratchet_message_keys)); free(cur_node); } node->message_keys_head = 0; @@ -1841,39 +1837,39 @@ static void session_state_free_receiver_chain(session_state *state) state->receiver_chain_head = 0; } -void session_state_destroy(axolotl_type_base *type) +void session_state_destroy(signal_type_base *type) { session_state *state = (session_state *)type; if(state->local_identity_public) { - AXOLOTL_UNREF(state->local_identity_public); + SIGNAL_UNREF(state->local_identity_public); } if(state->remote_identity_public) { - AXOLOTL_UNREF(state->remote_identity_public); + SIGNAL_UNREF(state->remote_identity_public); } if(state->root_key) { - AXOLOTL_UNREF(state->root_key); + SIGNAL_UNREF(state->root_key); } session_state_free_sender_chain(state); session_state_free_receiver_chain(state); if(state->has_pending_key_exchange) { if(state->pending_key_exchange.local_base_key) { - AXOLOTL_UNREF(state->pending_key_exchange.local_base_key); + SIGNAL_UNREF(state->pending_key_exchange.local_base_key); } if(state->pending_key_exchange.local_ratchet_key) { - AXOLOTL_UNREF(state->pending_key_exchange.local_ratchet_key); + SIGNAL_UNREF(state->pending_key_exchange.local_ratchet_key); } if(state->pending_key_exchange.local_identity_key) { - AXOLOTL_UNREF(state->pending_key_exchange.local_identity_key); + SIGNAL_UNREF(state->pending_key_exchange.local_identity_key); } } if(state->has_pending_pre_key) { if(state->pending_pre_key.base_key) { - AXOLOTL_UNREF(state->pending_pre_key.base_key); + SIGNAL_UNREF(state->pending_pre_key.base_key); } } if(state->alice_base_key) { - AXOLOTL_UNREF(state->alice_base_key); + SIGNAL_UNREF(state->alice_base_key); } free(state); } diff --git a/libs/libaxolotl/src/session_state.h b/libs/libaxolotl/src/session_state.h index 119e523fc9..ef1ecaed97 100644 --- a/libs/libaxolotl/src/session_state.h +++ b/libs/libaxolotl/src/session_state.h @@ -3,7 +3,7 @@ #include <stdint.h> #include <stddef.h> -#include "axolotl_types.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { @@ -11,10 +11,10 @@ extern "C" { /*------------------------------------------------------------------------*/ -int session_state_create(session_state **state, axolotl_context *global_context); -int session_state_serialize(axolotl_buffer **buffer, session_state *state); -int session_state_deserialize(session_state **state, const uint8_t *data, size_t len, axolotl_context *global_context); -int session_state_copy(session_state **state, session_state *other_state, axolotl_context *global_context); +int session_state_create(session_state **state, signal_context *global_context); +int session_state_serialize(signal_buffer **buffer, session_state *state); +int session_state_deserialize(session_state **state, const uint8_t *data, size_t len, signal_context *global_context); +int session_state_copy(session_state **state, session_state *other_state, signal_context *global_context); void session_state_set_session_version(session_state *state, uint32_t version); uint32_t session_state_get_session_version(const session_state *state); @@ -80,7 +80,7 @@ int session_state_get_needs_refresh(const session_state *state); void session_state_set_alice_base_key(session_state *state, ec_public_key *key); ec_public_key *session_state_get_alice_base_key(const session_state *state); -void session_state_destroy(axolotl_type_base *type); +void session_state_destroy(signal_type_base *type); #ifdef __cplusplus } diff --git a/libs/libaxolotl/src/signal.def b/libs/libaxolotl/src/signal.def new file mode 100755 index 0000000000..93cf408531 --- /dev/null +++ b/libs/libaxolotl/src/signal.def @@ -0,0 +1,55 @@ +LIBRARY libsignal-c.mir + +EXPORTS + signal_type_ref + signal_type_unref + signal_buffer_alloc + signal_buffer_create + signal_buffer_copy + signal_buffer_append + signal_buffer_data + signal_buffer_len + signal_buffer_compare + signal_buffer_free + signal_buffer_bzero_free + signal_buffer_list_alloc + signal_buffer_list_push + signal_buffer_list_size + signal_buffer_list_free + signal_int_list_alloc + signal_int_list_push_back + signal_int_list_size + signal_int_list_at + signal_int_list_free + signal_context_create + signal_context_set_crypto_provider + signal_context_set_locking_functions + signal_context_set_log_function + signal_context_destroy + signal_protocol_store_context_create + signal_protocol_store_context_set_session_store + signal_protocol_store_context_set_pre_key_store + signal_protocol_store_context_set_signed_pre_key_store + signal_protocol_store_context_set_identity_key_store + signal_protocol_store_context_set_sender_key_store + signal_protocol_store_context_destroy + signal_protocol_session_load_session + signal_protocol_session_get_sub_device_sessions + signal_protocol_session_store_session + signal_protocol_session_contains_session + signal_protocol_session_delete_session + signal_protocol_session_delete_all_sessions + signal_protocol_pre_key_load_key + signal_protocol_pre_key_store_key + signal_protocol_pre_key_contains_key + signal_protocol_pre_key_remove_key + signal_protocol_signed_pre_key_load_key + signal_protocol_signed_pre_key_store_key + signal_protocol_signed_pre_key_contains_key + signal_protocol_signed_pre_key_remove_key + signal_protocol_identity_get_key_pair + signal_protocol_identity_get_local_registration_id + signal_protocol_identity_save_identity + signal_protocol_identity_is_trusted_identity + signal_protocol_sender_key_store_key + signal_protocol_sender_key_load_key diff --git a/libs/libaxolotl/src/axolotl.c b/libs/libaxolotl/src/signal_protocol.c index 7db1cbfc88..30368ae3b6 100644 --- a/libs/libaxolotl/src/axolotl.c +++ b/libs/libaxolotl/src/signal_protocol.c @@ -1,5 +1,4 @@ -#include "axolotl.h" -#include "axolotl_internal.h" +#include "signal_protocol.h" #include <stdio.h> #include <stdlib.h> @@ -7,6 +6,8 @@ #include <string.h> #include <stdarg.h> #include <assert.h> + +#include "signal_protocol_internal.h" #include "utlist.h" #include "utarray.h" @@ -20,17 +21,17 @@ int type_ref_count = 0; int type_unref_count = 0; #endif -struct axolotl_store_context { - axolotl_context *global_context; - axolotl_session_store session_store; - axolotl_pre_key_store pre_key_store; - axolotl_signed_pre_key_store signed_pre_key_store; - axolotl_identity_key_store identity_key_store; - axolotl_sender_key_store sender_key_store; +struct signal_protocol_store_context { + signal_context *global_context; + signal_protocol_session_store session_store; + signal_protocol_pre_key_store pre_key_store; + signal_protocol_signed_pre_key_store signed_pre_key_store; + signal_protocol_identity_key_store identity_key_store; + signal_protocol_sender_key_store sender_key_store; }; -void axolotl_type_init(axolotl_type_base *instance, - void (*destroy_func)(axolotl_type_base *instance)) +void signal_type_init(signal_type_base *instance, + void (*destroy_func)(signal_type_base *instance)) { instance->ref_count = 1; instance->destroy = destroy_func; @@ -39,7 +40,7 @@ void axolotl_type_init(axolotl_type_base *instance, #endif } -void axolotl_type_ref(axolotl_type_base *instance) +void signal_type_ref(signal_type_base *instance) { #ifdef DEBUG_REFCOUNT type_ref_count++; @@ -49,7 +50,7 @@ void axolotl_type_ref(axolotl_type_base *instance) instance->ref_count++; } -void axolotl_type_unref(axolotl_type_base *instance) +void signal_type_unref(signal_type_base *instance) { if(instance) { #ifdef DEBUG_REFCOUNT @@ -66,31 +67,34 @@ void axolotl_type_unref(axolotl_type_base *instance) } #ifdef DEBUG_REFCOUNT -int axolotl_type_ref_count(axolotl_type_base *instance) +int signal_type_ref_count(signal_type_base *instance) { + if(!instance) { + return 0; + } return instance->ref_count; } #endif /*------------------------------------------------------------------------*/ -axolotl_buffer *axolotl_buffer_alloc(size_t len) +signal_buffer *signal_buffer_alloc(size_t len) { - axolotl_buffer *buffer; - if(len > (SIZE_MAX - sizeof(struct axolotl_buffer)) / sizeof(uint8_t)) { + signal_buffer *buffer; + if(len > (SIZE_MAX - sizeof(struct signal_buffer)) / sizeof(uint8_t)) { return 0; } - buffer = malloc(sizeof(struct axolotl_buffer) + (sizeof(uint8_t) * len)); + buffer = malloc(sizeof(struct signal_buffer) + (sizeof(uint8_t) * len)); if(buffer) { buffer->len = len; } return buffer; } -axolotl_buffer *axolotl_buffer_create(const uint8_t *data, size_t len) +signal_buffer *signal_buffer_create(const uint8_t *data, size_t len) { - axolotl_buffer *buffer = axolotl_buffer_alloc(len); + signal_buffer *buffer = signal_buffer_alloc(len); if(!buffer) { return 0; } @@ -99,16 +103,22 @@ axolotl_buffer *axolotl_buffer_create(const uint8_t *data, size_t len) return buffer; } -axolotl_buffer *axolotl_buffer_copy(const axolotl_buffer *buffer) +signal_buffer *signal_buffer_copy(const signal_buffer *buffer) { - return axolotl_buffer_create(buffer->data, buffer->len); + return signal_buffer_create(buffer->data, buffer->len); } -axolotl_buffer *axolotl_buffer_append(axolotl_buffer *buffer, const uint8_t *data, size_t len) +signal_buffer *signal_buffer_append(signal_buffer *buffer, const uint8_t *data, size_t len) { + signal_buffer *tmp_buffer; size_t previous_size = buffer->len; - size_t previous_alloc = sizeof(struct axolotl_buffer) + (sizeof(uint8_t) * previous_size); - axolotl_buffer *tmp_buffer = realloc(buffer, previous_alloc + (sizeof(uint8_t) * len)); + size_t previous_alloc = sizeof(struct signal_buffer) + (sizeof(uint8_t) * previous_size); + + if(len > (SIZE_MAX - previous_alloc)) { + return 0; + } + + tmp_buffer = realloc(buffer, previous_alloc + (sizeof(uint8_t) * len)); if(!tmp_buffer) { return 0; } @@ -118,17 +128,17 @@ axolotl_buffer *axolotl_buffer_append(axolotl_buffer *buffer, const uint8_t *dat return tmp_buffer; } -uint8_t *axolotl_buffer_data(axolotl_buffer *buffer) +uint8_t *signal_buffer_data(signal_buffer *buffer) { return buffer->data; } -size_t axolotl_buffer_len(axolotl_buffer *buffer) +size_t signal_buffer_len(signal_buffer *buffer) { return buffer->len; } -int axolotl_buffer_compare(axolotl_buffer *buffer1, axolotl_buffer *buffer2) +int signal_buffer_compare(signal_buffer *buffer1, signal_buffer *buffer2) { if(buffer1 == buffer2) { return 0; @@ -147,65 +157,65 @@ int axolotl_buffer_compare(axolotl_buffer *buffer1, axolotl_buffer *buffer2) return 1; } else { - return axolotl_constant_memcmp(buffer1->data, buffer2->data, buffer1->len); + return signal_constant_memcmp(buffer1->data, buffer2->data, buffer1->len); } } } -void axolotl_buffer_free(axolotl_buffer *buffer) +void signal_buffer_free(signal_buffer *buffer) { if(buffer) { free(buffer); } } -void axolotl_buffer_bzero_free(axolotl_buffer *buffer) +void signal_buffer_bzero_free(signal_buffer *buffer) { if(buffer) { - axolotl_explicit_bzero(buffer->data, buffer->len); + signal_explicit_bzero(buffer->data, buffer->len); free(buffer); } } /*------------------------------------------------------------------------*/ -typedef struct axolotl_buffer_list_node +typedef struct signal_buffer_list_node { - axolotl_buffer *buffer; - struct axolotl_buffer_list_node *next; -} axolotl_buffer_list_node; + signal_buffer *buffer; + struct signal_buffer_list_node *next; +} signal_buffer_list_node; -struct axolotl_buffer_list +struct signal_buffer_list { int size; - axolotl_buffer_list_node *head; + signal_buffer_list_node *head; }; -struct axolotl_int_list +struct signal_int_list { UT_array *values; }; -axolotl_buffer_list *axolotl_buffer_list_alloc() +signal_buffer_list *signal_buffer_list_alloc(void) { - axolotl_buffer_list *list = malloc(sizeof(axolotl_buffer_list)); + signal_buffer_list *list = malloc(sizeof(signal_buffer_list)); if(list) { - memset(list, 0, sizeof(axolotl_buffer_list)); + memset(list, 0, sizeof(signal_buffer_list)); } return list; } -int axolotl_buffer_list_push(axolotl_buffer_list *list, axolotl_buffer *buffer) +int signal_buffer_list_push(signal_buffer_list *list, signal_buffer *buffer) { - axolotl_buffer_list_node *node = 0; + signal_buffer_list_node *node = 0; assert(list); assert(buffer); - node = malloc(sizeof(axolotl_buffer_list_node)); + node = malloc(sizeof(signal_buffer_list_node)); if(!node) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } node->buffer = buffer; @@ -214,61 +224,61 @@ int axolotl_buffer_list_push(axolotl_buffer_list *list, axolotl_buffer *buffer) return 0; } -int axolotl_buffer_list_size(axolotl_buffer_list *list) +int signal_buffer_list_size(signal_buffer_list *list) { assert(list); return list->size; } -void axolotl_buffer_list_free(axolotl_buffer_list *list) +void signal_buffer_list_free(signal_buffer_list *list) { - axolotl_buffer_list_node *cur_node; - axolotl_buffer_list_node *tmp_node; + signal_buffer_list_node *cur_node; + signal_buffer_list_node *tmp_node; assert(list); LL_FOREACH_SAFE(list->head, cur_node, tmp_node) { LL_DELETE(list->head, cur_node); if(cur_node->buffer) { - axolotl_buffer_free(cur_node->buffer); + signal_buffer_free(cur_node->buffer); } free(cur_node); } free(list); } -axolotl_int_list *axolotl_int_list_alloc(); +signal_int_list *signal_int_list_alloc(); /*------------------------------------------------------------------------*/ -axolotl_int_list *axolotl_int_list_alloc() +signal_int_list *signal_int_list_alloc() { - axolotl_int_list *list = malloc(sizeof(axolotl_int_list)); + signal_int_list *list = malloc(sizeof(signal_int_list)); if(!list) { return 0; } - memset(list, 0, sizeof(axolotl_int_list)); + memset(list, 0, sizeof(signal_int_list)); utarray_new(list->values, &ut_int_icd); return list; } -void axolotl_int_list_push_back(axolotl_int_list *list, int value) +void signal_int_list_push_back(signal_int_list *list, int value) { assert(list); utarray_push_back(list->values, &value); } -unsigned int axolotl_int_list_size(axolotl_int_list *list) +unsigned int signal_int_list_size(signal_int_list *list) { assert(list); return utarray_len(list->values); } -int axolotl_int_list_at(axolotl_int_list *list, unsigned int index) +int signal_int_list_at(signal_int_list *list, unsigned int index) { int *value = 0; assert(list); - assert(index >= 0 && index < utarray_len(list->values)); + assert(index < utarray_len(list->values)); value = (int *)utarray_eltptr(list->values, index); @@ -277,7 +287,7 @@ int axolotl_int_list_at(axolotl_int_list *list, unsigned int index) return *value; } -void axolotl_int_list_free(axolotl_int_list *list) +void signal_int_list_free(signal_int_list *list) { if(list) { utarray_free(list->values); @@ -287,13 +297,13 @@ void axolotl_int_list_free(axolotl_int_list *list) /*------------------------------------------------------------------------*/ -int axolotl_context_create(axolotl_context **context, void *user_data) +int signal_context_create(signal_context **context, void *user_data) { - *context = malloc(sizeof(axolotl_context)); + *context = malloc(sizeof(signal_context)); if(!(*context)) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - memset(*context, 0, sizeof(axolotl_context)); + memset(*context, 0, sizeof(signal_context)); (*context)->user_data = user_data; #ifdef DEBUG_REFCOUNT type_ref_count = 0; @@ -302,7 +312,7 @@ int axolotl_context_create(axolotl_context **context, void *user_data) return 0; } -int axolotl_context_set_crypto_provider(axolotl_context *context, const axolotl_crypto_provider *crypto_provider) +int signal_context_set_crypto_provider(signal_context *context, const signal_crypto_provider *crypto_provider) { assert(context); if(!crypto_provider @@ -310,18 +320,18 @@ int axolotl_context_set_crypto_provider(axolotl_context *context, const axolotl_ || !crypto_provider->hmac_sha256_update_func || !crypto_provider->hmac_sha256_final_func || !crypto_provider->hmac_sha256_cleanup_func) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } - memcpy(&(context->crypto_provider), crypto_provider, sizeof(axolotl_crypto_provider)); + memcpy(&(context->crypto_provider), crypto_provider, sizeof(signal_crypto_provider)); return 0; } -int axolotl_context_set_locking_functions(axolotl_context *context, +int signal_context_set_locking_functions(signal_context *context, void (*lock)(void *user_data), void (*unlock)(void *user_data)) { assert(context); if((lock && !unlock) || (!lock && unlock)) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } context->lock = lock; @@ -329,7 +339,7 @@ int axolotl_context_set_locking_functions(axolotl_context *context, return 0; } -int axolotl_context_set_log_function(axolotl_context *context, +int signal_context_set_log_function(signal_context *context, void (*log)(int level, const char *message, size_t len, void *user_data)) { assert(context); @@ -337,7 +347,7 @@ int axolotl_context_set_log_function(axolotl_context *context, return 0; } -void axolotl_context_destroy(axolotl_context *context) +void signal_context_destroy(signal_context *context) { #ifdef DEBUG_REFCOUNT fprintf(stderr, "Global REF count: %d\n", type_ref_count); @@ -350,50 +360,71 @@ void axolotl_context_destroy(axolotl_context *context) /*------------------------------------------------------------------------*/ -int axolotl_crypto_random(axolotl_context *context, uint8_t *data, size_t len) +int signal_crypto_random(signal_context *context, uint8_t *data, size_t len) { assert(context); assert(context->crypto_provider.random_func); return context->crypto_provider.random_func(data, len, context->crypto_provider.user_data); } -int axolotl_hmac_sha256_init(axolotl_context *context, void **hmac_context, const uint8_t *key, size_t key_len) +int signal_hmac_sha256_init(signal_context *context, void **hmac_context, const uint8_t *key, size_t key_len) { assert(context); assert(context->crypto_provider.hmac_sha256_init_func); return context->crypto_provider.hmac_sha256_init_func(hmac_context, key, key_len, context->crypto_provider.user_data); } -int axolotl_hmac_sha256_update(axolotl_context *context, void *hmac_context, const uint8_t *data, size_t data_len) +int signal_hmac_sha256_update(signal_context *context, void *hmac_context, const uint8_t *data, size_t data_len) { assert(context); assert(context->crypto_provider.hmac_sha256_update_func); return context->crypto_provider.hmac_sha256_update_func(hmac_context, data, data_len, context->crypto_provider.user_data); } -int axolotl_hmac_sha256_final(axolotl_context *context, void *hmac_context, axolotl_buffer **output) +int signal_hmac_sha256_final(signal_context *context, void *hmac_context, signal_buffer **output) { assert(context); assert(context->crypto_provider.hmac_sha256_final_func); return context->crypto_provider.hmac_sha256_final_func(hmac_context, output, context->crypto_provider.user_data); } -void axolotl_hmac_sha256_cleanup(axolotl_context *context, void *hmac_context) +void signal_hmac_sha256_cleanup(signal_context *context, void *hmac_context) { assert(context); assert(context->crypto_provider.hmac_sha256_cleanup_func); context->crypto_provider.hmac_sha256_cleanup_func(hmac_context, context->crypto_provider.user_data); } -int axolotl_sha512_digest(axolotl_context *context, axolotl_buffer **output, const uint8_t *data, size_t data_len) +int signal_sha512_digest_init(signal_context *context, void **digest_context) +{ + assert(context); + assert(context->crypto_provider.sha512_digest_init_func); + return context->crypto_provider.sha512_digest_init_func(digest_context, context->crypto_provider.user_data); +} + +int signal_sha512_digest_update(signal_context *context, void *digest_context, const uint8_t *data, size_t data_len) { assert(context); - assert(context->crypto_provider.sha512_digest_func); - return context->crypto_provider.sha512_digest_func(output, data, data_len, context->crypto_provider.user_data); + assert(context->crypto_provider.sha512_digest_update_func); + return context->crypto_provider.sha512_digest_update_func(digest_context, data, data_len, context->crypto_provider.user_data); } -int axolotl_encrypt(axolotl_context *context, - axolotl_buffer **output, +int signal_sha512_digest_final(signal_context *context, void *digest_context, signal_buffer **output) +{ + assert(context); + assert(context->crypto_provider.sha512_digest_final_func); + return context->crypto_provider.sha512_digest_final_func(digest_context, output, context->crypto_provider.user_data); +} + +void signal_sha512_digest_cleanup(signal_context *context, void *digest_context) +{ + assert(context); + assert(context->crypto_provider.sha512_digest_cleanup_func); + return context->crypto_provider.sha512_digest_cleanup_func(digest_context, context->crypto_provider.user_data); +} + +int signal_encrypt(signal_context *context, + signal_buffer **output, int cipher, const uint8_t *key, size_t key_len, const uint8_t *iv, size_t iv_len, @@ -407,8 +438,8 @@ int axolotl_encrypt(axolotl_context *context, context->crypto_provider.user_data); } -int axolotl_decrypt(axolotl_context *context, - axolotl_buffer **output, +int signal_decrypt(signal_context *context, + signal_buffer **output, int cipher, const uint8_t *key, size_t key_len, const uint8_t *iv, size_t iv_len, @@ -422,25 +453,25 @@ int axolotl_decrypt(axolotl_context *context, context->crypto_provider.user_data); } -void axolotl_lock(axolotl_context *context) +void signal_lock(signal_context *context) { if(context->lock) { context->lock(context->user_data); } } -void axolotl_unlock(axolotl_context *context) +void signal_unlock(signal_context *context) { if(context->unlock) { context->unlock(context->user_data); } } -void axolotl_log(axolotl_context *context, int level, const char *format, ...) +void signal_log(signal_context *context, int level, const char *format, ...) { char buf[256]; int n; - if(context->log) { + if(context && context->log) { va_list args; va_start(args, format); n = vsnprintf(buf, sizeof(buf), format, args); @@ -451,7 +482,7 @@ void axolotl_log(axolotl_context *context, int level, const char *format, ...) } } -void axolotl_explicit_bzero(void *v, size_t n) +void signal_explicit_bzero(void *v, size_t n) { #ifdef HAVE_SECUREZEROMEMORY SecureZeroMemory(v, n); @@ -463,7 +494,7 @@ void axolotl_explicit_bzero(void *v, size_t n) #endif } -int axolotl_constant_memcmp(const void *s1, const void *s2, size_t n) +int signal_constant_memcmp(const void *s1, const void *s2, size_t n) { size_t i; const unsigned char *c1 = (const unsigned char *) s1; @@ -477,7 +508,7 @@ int axolotl_constant_memcmp(const void *s1, const void *s2, size_t n) return result; } -void axolotl_str_serialize_protobuf(ProtobufCBinaryData *buffer, const char *str) +void signal_protocol_str_serialize_protobuf(ProtobufCBinaryData *buffer, const char *str) { assert(buffer); assert(str); @@ -485,7 +516,7 @@ void axolotl_str_serialize_protobuf(ProtobufCBinaryData *buffer, const char *str buffer->len = strlen(str); } -char *axolotl_str_deserialize_protobuf(ProtobufCBinaryData *buffer) +char *signal_protocol_str_deserialize_protobuf(ProtobufCBinaryData *buffer) { char *str = 0; assert(buffer); @@ -503,64 +534,64 @@ char *axolotl_str_deserialize_protobuf(ProtobufCBinaryData *buffer) /*------------------------------------------------------------------------*/ -int axolotl_store_context_create(axolotl_store_context **context, axolotl_context *global_context) +int signal_protocol_store_context_create(signal_protocol_store_context **context, signal_context *global_context) { assert(global_context); - *context = malloc(sizeof(axolotl_store_context)); + *context = malloc(sizeof(signal_protocol_store_context)); if(!(*context)) { - return AX_ERR_NOMEM; + return SG_ERR_NOMEM; } - memset(*context, 0, sizeof(axolotl_store_context)); + memset(*context, 0, sizeof(signal_protocol_store_context)); (*context)->global_context = global_context; return 0; } -int axolotl_store_context_set_session_store(axolotl_store_context *context, const axolotl_session_store *store) +int signal_protocol_store_context_set_session_store(signal_protocol_store_context *context, const signal_protocol_session_store *store) { if(!store) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } - memcpy(&(context->session_store), store, sizeof(axolotl_session_store)); + memcpy(&(context->session_store), store, sizeof(signal_protocol_session_store)); return 0; } -int axolotl_store_context_set_pre_key_store(axolotl_store_context *context, const axolotl_pre_key_store *store) +int signal_protocol_store_context_set_pre_key_store(signal_protocol_store_context *context, const signal_protocol_pre_key_store *store) { if(!store) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } - memcpy(&(context->pre_key_store), store, sizeof(axolotl_pre_key_store)); + memcpy(&(context->pre_key_store), store, sizeof(signal_protocol_pre_key_store)); return 0; } -int axolotl_store_context_set_signed_pre_key_store(axolotl_store_context *context, const axolotl_signed_pre_key_store *store) +int signal_protocol_store_context_set_signed_pre_key_store(signal_protocol_store_context *context, const signal_protocol_signed_pre_key_store *store) { if(!store) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } - memcpy(&(context->signed_pre_key_store), store, sizeof(axolotl_signed_pre_key_store)); + memcpy(&(context->signed_pre_key_store), store, sizeof(signal_protocol_signed_pre_key_store)); return 0; } -int axolotl_store_context_set_identity_key_store(axolotl_store_context *context, const axolotl_identity_key_store *store) +int signal_protocol_store_context_set_identity_key_store(signal_protocol_store_context *context, const signal_protocol_identity_key_store *store) { if(!store) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } - memcpy(&(context->identity_key_store), store, sizeof(axolotl_identity_key_store)); + memcpy(&(context->identity_key_store), store, sizeof(signal_protocol_identity_key_store)); return 0; } -int axolotl_store_context_set_sender_key_store(axolotl_store_context *context, const axolotl_sender_key_store *store) +int signal_protocol_store_context_set_sender_key_store(signal_protocol_store_context *context, const signal_protocol_sender_key_store *store) { if(!store) { - return AX_ERR_INVAL; + return SG_ERR_INVAL; } - memcpy(&(context->sender_key_store), store, sizeof(axolotl_sender_key_store)); + memcpy(&(context->sender_key_store), store, sizeof(signal_protocol_sender_key_store)); return 0; } -void axolotl_store_context_destroy(axolotl_store_context *context) +void signal_protocol_store_context_destroy(signal_protocol_store_context *context) { if(context) { if(context->session_store.destroy_func) { @@ -584,10 +615,10 @@ void axolotl_store_context_destroy(axolotl_store_context *context) /*------------------------------------------------------------------------*/ -int axolotl_session_load_session(axolotl_store_context *context, session_record **record, const axolotl_address *address) +int signal_protocol_session_load_session(signal_protocol_store_context *context, session_record **record, const signal_protocol_address *address) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; session_record *result_record = 0; assert(context); @@ -602,7 +633,7 @@ int axolotl_session_load_session(axolotl_store_context *context, session_record if(result == 0) { if(buffer) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } result = session_record_create(&result_record, 0, context->global_context); @@ -613,15 +644,15 @@ int axolotl_session_load_session(axolotl_store_context *context, session_record goto complete; } result = session_record_deserialize(&result_record, - axolotl_buffer_data(buffer), axolotl_buffer_len(buffer), context->global_context); + signal_buffer_data(buffer), signal_buffer_len(buffer), context->global_context); } else { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; } complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } if(result >= 0) { *record = result_record; @@ -629,7 +660,7 @@ complete: return result; } -int axolotl_session_get_sub_device_sessions(axolotl_store_context *context, axolotl_int_list **sessions, const char *name, size_t name_len) +int signal_protocol_session_get_sub_device_sessions(signal_protocol_store_context *context, signal_int_list **sessions, const char *name, size_t name_len) { assert(context); assert(context->session_store.get_sub_device_sessions_func); @@ -639,10 +670,10 @@ int axolotl_session_get_sub_device_sessions(axolotl_store_context *context, axol context->session_store.user_data); } -int axolotl_session_store_session(axolotl_store_context *context, const axolotl_address *address, session_record *record) +int signal_protocol_session_store_session(signal_protocol_store_context *context, const signal_protocol_address *address, session_record *record) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; assert(context); assert(context->session_store.store_session_func); @@ -655,18 +686,18 @@ int axolotl_session_store_session(axolotl_store_context *context, const axolotl_ result = context->session_store.store_session_func( address, - axolotl_buffer_data(buffer), axolotl_buffer_len(buffer), + signal_buffer_data(buffer), signal_buffer_len(buffer), context->session_store.user_data); complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } return result; } -int axolotl_session_contains_session(axolotl_store_context *context, const axolotl_address *address) +int signal_protocol_session_contains_session(signal_protocol_store_context *context, const signal_protocol_address *address) { assert(context); assert(context->session_store.contains_session_func); @@ -676,7 +707,7 @@ int axolotl_session_contains_session(axolotl_store_context *context, const axolo context->session_store.user_data); } -int axolotl_session_delete_session(axolotl_store_context *context, const axolotl_address *address) +int signal_protocol_session_delete_session(signal_protocol_store_context *context, const signal_protocol_address *address) { assert(context); assert(context->session_store.delete_session_func); @@ -686,7 +717,7 @@ int axolotl_session_delete_session(axolotl_store_context *context, const axolotl context->session_store.user_data); } -int axolotl_session_delete_all_sessions(axolotl_store_context *context, const char *name, size_t name_len) +int signal_protocol_session_delete_all_sessions(signal_protocol_store_context *context, const char *name, size_t name_len) { assert(context); assert(context->session_store.delete_all_sessions_func); @@ -698,10 +729,10 @@ int axolotl_session_delete_all_sessions(axolotl_store_context *context, const ch /*------------------------------------------------------------------------*/ -int axolotl_pre_key_load_key(axolotl_store_context *context, session_pre_key **pre_key, uint32_t pre_key_id) +int signal_protocol_pre_key_load_key(signal_protocol_store_context *context, session_pre_key **pre_key, uint32_t pre_key_id) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; session_pre_key *result_key = 0; assert(context); @@ -715,11 +746,11 @@ int axolotl_pre_key_load_key(axolotl_store_context *context, session_pre_key **p } result = session_pre_key_deserialize(&result_key, - axolotl_buffer_data(buffer), axolotl_buffer_len(buffer), context->global_context); + signal_buffer_data(buffer), signal_buffer_len(buffer), context->global_context); complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } if(result >= 0) { *pre_key = result_key; @@ -727,10 +758,10 @@ complete: return result; } -int axolotl_pre_key_store_key(axolotl_store_context *context, session_pre_key *pre_key) +int signal_protocol_pre_key_store_key(signal_protocol_store_context *context, session_pre_key *pre_key) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; uint32_t id = 0; assert(context); @@ -746,18 +777,18 @@ int axolotl_pre_key_store_key(axolotl_store_context *context, session_pre_key *p result = context->pre_key_store.store_pre_key( id, - axolotl_buffer_data(buffer), axolotl_buffer_len(buffer), + signal_buffer_data(buffer), signal_buffer_len(buffer), context->pre_key_store.user_data); complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } return result; } -int axolotl_pre_key_contains_key(axolotl_store_context *context, uint32_t pre_key_id) +int signal_protocol_pre_key_contains_key(signal_protocol_store_context *context, uint32_t pre_key_id) { int result = 0; @@ -770,7 +801,7 @@ int axolotl_pre_key_contains_key(axolotl_store_context *context, uint32_t pre_ke return result; } -int axolotl_pre_key_remove_key(axolotl_store_context *context, uint32_t pre_key_id) +int signal_protocol_pre_key_remove_key(signal_protocol_store_context *context, uint32_t pre_key_id) { int result = 0; @@ -785,10 +816,10 @@ int axolotl_pre_key_remove_key(axolotl_store_context *context, uint32_t pre_key_ /*------------------------------------------------------------------------*/ -int axolotl_signed_pre_key_load_key(axolotl_store_context *context, session_signed_pre_key **pre_key, uint32_t signed_pre_key_id) +int signal_protocol_signed_pre_key_load_key(signal_protocol_store_context *context, session_signed_pre_key **pre_key, uint32_t signed_pre_key_id) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; session_signed_pre_key *result_key = 0; assert(context); @@ -802,11 +833,11 @@ int axolotl_signed_pre_key_load_key(axolotl_store_context *context, session_sign } result = session_signed_pre_key_deserialize(&result_key, - axolotl_buffer_data(buffer), axolotl_buffer_len(buffer), context->global_context); + signal_buffer_data(buffer), signal_buffer_len(buffer), context->global_context); complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } if(result >= 0) { *pre_key = result_key; @@ -814,10 +845,10 @@ complete: return result; } -int axolotl_signed_pre_key_store_key(axolotl_store_context *context, session_signed_pre_key *pre_key) +int signal_protocol_signed_pre_key_store_key(signal_protocol_store_context *context, session_signed_pre_key *pre_key) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; uint32_t id = 0; assert(context); @@ -833,18 +864,18 @@ int axolotl_signed_pre_key_store_key(axolotl_store_context *context, session_sig result = context->signed_pre_key_store.store_signed_pre_key( id, - axolotl_buffer_data(buffer), axolotl_buffer_len(buffer), + signal_buffer_data(buffer), signal_buffer_len(buffer), context->signed_pre_key_store.user_data); complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } return result; } -int axolotl_signed_pre_key_contains_key(axolotl_store_context *context, uint32_t signed_pre_key_id) +int signal_protocol_signed_pre_key_contains_key(signal_protocol_store_context *context, uint32_t signed_pre_key_id) { int result = 0; @@ -857,7 +888,7 @@ int axolotl_signed_pre_key_contains_key(axolotl_store_context *context, uint32_t return result; } -int axolotl_signed_pre_key_remove_key(axolotl_store_context *context, uint32_t signed_pre_key_id) +int signal_protocol_signed_pre_key_remove_key(signal_protocol_store_context *context, uint32_t signed_pre_key_id) { int result = 0; @@ -872,11 +903,11 @@ int axolotl_signed_pre_key_remove_key(axolotl_store_context *context, uint32_t s /*------------------------------------------------------------------------*/ -int axolotl_identity_get_key_pair(axolotl_store_context *context, ratchet_identity_key_pair **key_pair) +int signal_protocol_identity_get_key_pair(signal_protocol_store_context *context, ratchet_identity_key_pair **key_pair) { int result = 0; - axolotl_buffer *public_buf = 0; - axolotl_buffer *private_buf = 0; + signal_buffer *public_buf = 0; + signal_buffer *private_buf = 0; ec_public_key *public_key = 0; ec_private_key *private_key = 0; ratchet_identity_key_pair *result_key = 0; @@ -908,16 +939,16 @@ int axolotl_identity_get_key_pair(axolotl_store_context *context, ratchet_identi complete: if(public_buf) { - axolotl_buffer_free(public_buf); + signal_buffer_free(public_buf); } if(private_buf) { - axolotl_buffer_free(private_buf); + signal_buffer_free(private_buf); } if(public_key) { - AXOLOTL_UNREF(public_key); + SIGNAL_UNREF(public_key); } if(private_key) { - AXOLOTL_UNREF(private_key); + SIGNAL_UNREF(private_key); } if(result >= 0) { *key_pair = result_key; @@ -925,7 +956,7 @@ complete: return result; } -int axolotl_identity_get_local_registration_id(axolotl_store_context *context, uint32_t *registration_id) +int signal_protocol_identity_get_local_registration_id(signal_protocol_store_context *context, uint32_t *registration_id) { int result = 0; @@ -938,10 +969,10 @@ int axolotl_identity_get_local_registration_id(axolotl_store_context *context, u return result; } -int axolotl_identity_save_identity(axolotl_store_context *context, const char *name, size_t name_len, ec_public_key *identity_key) +int signal_protocol_identity_save_identity(signal_protocol_store_context *context, const signal_protocol_address *address, ec_public_key *identity_key) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; assert(context); assert(context->identity_key_store.save_identity); @@ -953,29 +984,29 @@ int axolotl_identity_save_identity(axolotl_store_context *context, const char *n } result = context->identity_key_store.save_identity( - name, name_len, - axolotl_buffer_data(buffer), - axolotl_buffer_len(buffer), + address, + signal_buffer_data(buffer), + signal_buffer_len(buffer), context->identity_key_store.user_data); } else { result = context->identity_key_store.save_identity( - name, name_len, 0, 0, + address, 0, 0, context->identity_key_store.user_data); } complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } return result; } -int axolotl_identity_is_trusted_identity(axolotl_store_context *context, const char *name, size_t name_len, ec_public_key *identity_key) +int signal_protocol_identity_is_trusted_identity(signal_protocol_store_context *context, const signal_protocol_address *address, ec_public_key *identity_key) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; assert(context); assert(context->identity_key_store.is_trusted_identity); @@ -986,22 +1017,22 @@ int axolotl_identity_is_trusted_identity(axolotl_store_context *context, const c } result = context->identity_key_store.is_trusted_identity( - name, name_len, - axolotl_buffer_data(buffer), - axolotl_buffer_len(buffer), + address, + signal_buffer_data(buffer), + signal_buffer_len(buffer), context->identity_key_store.user_data); complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } return result; } -int axolotl_sender_key_store_key(axolotl_store_context *context, const axolotl_sender_key_name *sender_key_name, sender_key_record *record) +int signal_protocol_sender_key_store_key(signal_protocol_store_context *context, const signal_protocol_sender_key_name *sender_key_name, sender_key_record *record) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; assert(context); assert(context->sender_key_store.store_sender_key); @@ -1014,21 +1045,21 @@ int axolotl_sender_key_store_key(axolotl_store_context *context, const axolotl_s result = context->sender_key_store.store_sender_key( sender_key_name, - axolotl_buffer_data(buffer), axolotl_buffer_len(buffer), + signal_buffer_data(buffer), signal_buffer_len(buffer), context->sender_key_store.user_data); complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } return result; } -int axolotl_sender_key_load_key(axolotl_store_context *context, sender_key_record **record, const axolotl_sender_key_name *sender_key_name) +int signal_protocol_sender_key_load_key(signal_protocol_store_context *context, sender_key_record **record, const signal_protocol_sender_key_name *sender_key_name) { int result = 0; - axolotl_buffer *buffer = 0; + signal_buffer *buffer = 0; sender_key_record *result_record = 0; assert(context); @@ -1043,7 +1074,7 @@ int axolotl_sender_key_load_key(axolotl_store_context *context, sender_key_recor if(result == 0) { if(buffer) { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; goto complete; } result = sender_key_record_create(&result_record, context->global_context); @@ -1054,15 +1085,15 @@ int axolotl_sender_key_load_key(axolotl_store_context *context, sender_key_recor goto complete; } result = sender_key_record_deserialize(&result_record, - axolotl_buffer_data(buffer), axolotl_buffer_len(buffer), context->global_context); + signal_buffer_data(buffer), signal_buffer_len(buffer), context->global_context); } else { - result = AX_ERR_UNKNOWN; + result = SG_ERR_UNKNOWN; } complete: if(buffer) { - axolotl_buffer_free(buffer); + signal_buffer_free(buffer); } if(result >= 0) { *record = result_record; diff --git a/libs/libaxolotl/src/axolotl.h b/libs/libaxolotl/src/signal_protocol.h index 7fe03691d2..3b78a74be7 100644 --- a/libs/libaxolotl/src/axolotl.h +++ b/libs/libaxolotl/src/signal_protocol.h @@ -1,42 +1,43 @@ -#ifndef AXOLOTL_H -#define AXOLOTL_H +#ifndef SIGNAL_PROTOCOL_H +#define SIGNAL_PROTOCOL_H #include <stdio.h> #include <stdlib.h> #include <stdint.h> -#include "axolotl_types.h" #include "ratchet.h" #include "curve.h" #include "session_record.h" #include "session_pre_key.h" #include "sender_key_record.h" +#include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { #endif -#define AX_SUCCESS 0 +#define SG_SUCCESS 0 /* Standard error codes with values that match errno.h equivalents */ -#define AX_ERR_NOMEM -12 /* Not enough space */ -#define AX_ERR_INVAL -22 /* Invalid argument */ +#define SG_ERR_NOMEM -12 /* Not enough space */ +#define SG_ERR_INVAL -22 /* Invalid argument */ /* Custom error codes for error conditions specific to the library */ -#define AX_ERR_UNKNOWN -1000 -#define AX_ERR_DUPLICATE_MESSAGE -1001 -#define AX_ERR_INVALID_KEY -1002 -#define AX_ERR_INVALID_KEY_ID -1003 -#define AX_ERR_INVALID_MAC -1004 -#define AX_ERR_INVALID_MESSAGE -1005 -#define AX_ERR_INVALID_VERSION -1006 -#define AX_ERR_LEGACY_MESSAGE -1007 -#define AX_ERR_NO_SESSION -1008 -#define AX_ERR_STALE_KEY_EXCHANGE -1009 -#define AX_ERR_UNTRUSTED_IDENTITY -1010 -#define AX_ERR_INVALID_PROTO_BUF -1100 -#define AX_ERR_FP_VERSION_MISMATCH -1200 -#define AX_ERR_FP_IDENT_MISMATCH -1201 +#define SG_ERR_UNKNOWN -1000 +#define SG_ERR_DUPLICATE_MESSAGE -1001 +#define SG_ERR_INVALID_KEY -1002 +#define SG_ERR_INVALID_KEY_ID -1003 +#define SG_ERR_INVALID_MAC -1004 +#define SG_ERR_INVALID_MESSAGE -1005 +#define SG_ERR_INVALID_VERSION -1006 +#define SG_ERR_LEGACY_MESSAGE -1007 +#define SG_ERR_NO_SESSION -1008 +#define SG_ERR_STALE_KEY_EXCHANGE -1009 +#define SG_ERR_UNTRUSTED_IDENTITY -1010 +#define SG_ERR_VRF_SIG_VERIF_FAILED -1011 +#define SG_ERR_INVALID_PROTO_BUF -1100 +#define SG_ERR_FP_VERSION_MISMATCH -1200 +#define SG_ERR_FP_IDENT_MISMATCH -1201 /* * Minimum negative error code value that this library may use. @@ -44,36 +45,36 @@ extern "C" { * less than this constant will ensure that application-specific * errors can be distinguished from library errors. */ -#define AX_ERR_MINIMUM -9999 +#define SG_ERR_MINIMUM -9999 /* Log levels */ -#define AX_LOG_ERROR 0 -#define AX_LOG_WARNING 1 -#define AX_LOG_NOTICE 2 -#define AX_LOG_INFO 3 -#define AX_LOG_DEBUG 4 +#define SG_LOG_ERROR 0 +#define SG_LOG_WARNING 1 +#define SG_LOG_NOTICE 2 +#define SG_LOG_INFO 3 +#define SG_LOG_DEBUG 4 /* Mode settings for the crypto callbacks */ -#define AX_CIPHER_AES_CTR_NOPADDING 1 -#define AX_CIPHER_AES_CBC_PKCS5 2 +#define SG_CIPHER_AES_CTR_NOPADDING 1 +#define SG_CIPHER_AES_CBC_PKCS5 2 -void axolotl_type_ref(axolotl_type_base *instance); -void axolotl_type_unref(axolotl_type_base *instance); +void signal_type_ref(signal_type_base *instance); +void signal_type_unref(signal_type_base *instance); #ifdef DEBUG_REFCOUNT -int axolotl_type_ref_count(axolotl_type_base *instance); -#define AXOLOTL_REF(instance) do { \ - axolotl_type_ref((axolotl_type_base *)instance); \ - fprintf(stderr, "REF: " #instance " = %d\n", axolotl_type_ref_count((axolotl_type_base *)instance)); \ +int signal_type_ref_count(signal_type_base *instance); +#define SIGNAL_REF(instance) do { \ + signal_type_ref((signal_type_base *)instance); \ + fprintf(stderr, "REF: " #instance " = %d\n", signal_type_ref_count((signal_type_base *)instance)); \ } while (0) -#define AXOLOTL_UNREF(instance) do { \ - fprintf(stderr, "UNREF: " #instance " = %d\n", axolotl_type_ref_count((axolotl_type_base *)instance)); \ - axolotl_type_unref((axolotl_type_base *)instance); \ +#define SIGNAL_UNREF(instance) do { \ + fprintf(stderr, "UNREF: " #instance " = %d\n", signal_type_ref_count((signal_type_base *)instance)); \ + signal_type_unref((signal_type_base *)instance); \ instance = 0; \ } while(0) #else -#define AXOLOTL_REF(instance) axolotl_type_ref((axolotl_type_base *)instance) -#define AXOLOTL_UNREF(instance) do { axolotl_type_unref((axolotl_type_base *)instance); instance = 0; } while(0) +#define SIGNAL_REF(instance) signal_type_ref((signal_type_base *)instance) +#define SIGNAL_UNREF(instance) do { signal_type_unref((signal_type_base *)instance); instance = 0; } while(0) #endif /** @@ -82,7 +83,7 @@ int axolotl_type_ref_count(axolotl_type_base *instance); * @param len length of the buffer to allocate * @return pointer to the allocated buffer, or 0 on failure */ -axolotl_buffer *axolotl_buffer_alloc(size_t len); +signal_buffer *signal_buffer_alloc(size_t len); /** * Create a new buffer and copy the provided data into it. @@ -91,7 +92,7 @@ axolotl_buffer *axolotl_buffer_alloc(size_t len); * @param len length of the data * @return pointer to the allocated buffer, or 0 on failure */ -axolotl_buffer *axolotl_buffer_create(const uint8_t *data, size_t len); +signal_buffer *signal_buffer_create(const uint8_t *data, size_t len); /** * Create a copy of an existing buffer. @@ -99,7 +100,7 @@ axolotl_buffer *axolotl_buffer_create(const uint8_t *data, size_t len); * @param buffer the existing buffer to copy * @return pointer to the updated buffer, or 0 on failure */ -axolotl_buffer *axolotl_buffer_copy(const axolotl_buffer *buffer); +signal_buffer *signal_buffer_copy(const signal_buffer *buffer); /** * Append the provided data to an existing buffer. @@ -112,7 +113,7 @@ axolotl_buffer *axolotl_buffer_copy(const axolotl_buffer *buffer); * @param len length of the data * @return pointer to the updated buffer, or 0 on failure */ -axolotl_buffer *axolotl_buffer_append(axolotl_buffer *buffer, const uint8_t *data, size_t len); +signal_buffer *signal_buffer_append(signal_buffer *buffer, const uint8_t *data, size_t len); /** * Gets the data pointer for the buffer. @@ -121,7 +122,7 @@ axolotl_buffer *axolotl_buffer_append(axolotl_buffer *buffer, const uint8_t *dat * @param buffer pointer to the buffer instance * @return data pointer */ -uint8_t *axolotl_buffer_data(axolotl_buffer *buffer); +uint8_t *signal_buffer_data(signal_buffer *buffer); /** * Gets the length of the data stored within the buffer. @@ -129,7 +130,7 @@ uint8_t *axolotl_buffer_data(axolotl_buffer *buffer); * @param buffer pointer to the buffer instance * @return data length */ -size_t axolotl_buffer_len(axolotl_buffer *buffer); +size_t signal_buffer_len(signal_buffer *buffer); /** * Compare two buffers. @@ -138,14 +139,14 @@ size_t axolotl_buffer_len(axolotl_buffer *buffer); * @param buffer2 second buffer to compare * @return 0 if the two buffers are equal, negative or positive otherwise */ -int axolotl_buffer_compare(axolotl_buffer *buffer1, axolotl_buffer *buffer2); +int signal_buffer_compare(signal_buffer *buffer1, signal_buffer *buffer2); /** * Free the data buffer. * * @param buffer pointer to the buffer instance to free */ -void axolotl_buffer_free(axolotl_buffer *buffer); +void signal_buffer_free(signal_buffer *buffer); /** * Zero and free the data buffer. @@ -154,14 +155,14 @@ void axolotl_buffer_free(axolotl_buffer *buffer); * * @param buffer pointer to the buffer instance to free */ -void axolotl_buffer_bzero_free(axolotl_buffer *buffer); +void signal_buffer_bzero_free(signal_buffer *buffer); /** * Allocate a new buffer list. * * @return pointer to the allocated buffer, or 0 on failure */ -axolotl_buffer_list *axolotl_buffer_list_alloc(); +signal_buffer_list *signal_buffer_list_alloc(void); /** * Push the provided buffer onto the head of the list. @@ -170,7 +171,7 @@ axolotl_buffer_list *axolotl_buffer_list_alloc(); * @param buffer the buffer to push * @return 0 on success, or negative on failure */ -int axolotl_buffer_list_push(axolotl_buffer_list *list, axolotl_buffer *buffer); +int signal_buffer_list_push(signal_buffer_list *list, signal_buffer *buffer); /** * Gets the size of the buffer list. @@ -178,21 +179,21 @@ int axolotl_buffer_list_push(axolotl_buffer_list *list, axolotl_buffer *buffer); * @param list the buffer list * @return the size of the list */ -int axolotl_buffer_list_size(axolotl_buffer_list *list); +int signal_buffer_list_size(signal_buffer_list *list); /** * Free the buffer list, including all the buffers added to it. * * @param list the buffer list */ -void axolotl_buffer_list_free(axolotl_buffer_list *list); +void signal_buffer_list_free(signal_buffer_list *list); /** * Allocate a new int list * * @return pointer to the allocated buffer, or 0 on failure */ -axolotl_int_list *axolotl_int_list_alloc(); +signal_int_list *signal_int_list_alloc(void); /** * Push a new value onto the end of the list @@ -200,7 +201,7 @@ axolotl_int_list *axolotl_int_list_alloc(); * @param list the list * @param value the value to push */ -void axolotl_int_list_push_back(axolotl_int_list *list, int value); +void signal_int_list_push_back(signal_int_list *list, int value); /** * Gets the size of the list. @@ -208,7 +209,7 @@ void axolotl_int_list_push_back(axolotl_int_list *list, int value); * @param list the list * @return the size of the list */ -unsigned int axolotl_int_list_size(axolotl_int_list *list); +unsigned int signal_int_list_size(signal_int_list *list); /** * Gets the value of the element at a particular index in the list @@ -217,15 +218,15 @@ unsigned int axolotl_int_list_size(axolotl_int_list *list); * @param index the index within the list * @return the value */ -int axolotl_int_list_at(axolotl_int_list *list, unsigned int index); +int signal_int_list_at(signal_int_list *list, unsigned int index); /** * Free the int list * @param list the list to free */ -void axolotl_int_list_free(axolotl_int_list *list); +void signal_int_list_free(signal_int_list *list); -typedef struct axolotl_crypto_provider { +typedef struct signal_crypto_provider { /** * Callback for a secure random number generator. * This function shall fill the provided buffer with random bytes. @@ -267,7 +268,7 @@ typedef struct axolotl_crypto_provider { * @param output buffer to be allocated and populated with the result * @return 0 on success, negative on failure */ - int (*hmac_sha256_final_func)(void *hmac_context, axolotl_buffer **output, void *user_data); + int (*hmac_sha256_final_func)(void *hmac_context, signal_buffer **output, void *user_data); /** * Callback for an HMAC-SHA256 implementation. @@ -280,20 +281,49 @@ typedef struct axolotl_crypto_provider { /** * Callback for a SHA512 message digest implementation. - * This function is currently only used by the fingerprint generator. + * This function shall initialize a digest context. * - * @param output buffer to be allocated and populated with the ciphertext + * @param digest_context private digest context pointer + * @return 0 on success, negative on failure + */ + int (*sha512_digest_init_func)(void **digest_context, void *user_data); + + /** + * Callback for a SHA512 message digest implementation. + * This function shall update the digest context with the provided data. + * + * @param digest_context private digest context pointer * @param data pointer to the data * @param data_len length of the data * @return 0 on success, negative on failure */ - int (*sha512_digest_func)(axolotl_buffer **output, const uint8_t *data, size_t data_len, void *user_data); + int (*sha512_digest_update_func)(void *digest_context, const uint8_t *data, size_t data_len, void *user_data); + + /** + * Callback for a SHA512 message digest implementation. + * This function shall finalize the digest calculation, populate the + * output buffer with the result, and prepare the context for reuse. + * + * @param digest_context private digest context pointer + * @param output buffer to be allocated and populated with the result + * @return 0 on success, negative on failure + */ + int (*sha512_digest_final_func)(void *digest_context, signal_buffer **output, void *user_data); + + /** + * Callback for a SHA512 message digest implementation. + * This function shall free the private context allocated in + * sha512_digest_init_func. + * + * @param digest_context private digest context pointer + */ + void (*sha512_digest_cleanup_func)(void *digest_context, void *user_data); /** * Callback for an AES encryption implementation. * * @param output buffer to be allocated and populated with the ciphertext - * @param cipher specific cipher variant to use, either AX_CIPHER_AES_CTR_NOPADDING or AX_CIPHER_AES_CBC_PKCS5 + * @param cipher specific cipher variant to use, either SG_CIPHER_AES_CTR_NOPADDING or SG_CIPHER_AES_CBC_PKCS5 * @param key the encryption key * @param key_len length of the encryption key * @param iv the initialization vector @@ -302,7 +332,7 @@ typedef struct axolotl_crypto_provider { * @param plaintext_len length of the plaintext * @return 0 on success, negative on failure */ - int (*encrypt_func)(axolotl_buffer **output, + int (*encrypt_func)(signal_buffer **output, int cipher, const uint8_t *key, size_t key_len, const uint8_t *iv, size_t iv_len, @@ -313,7 +343,7 @@ typedef struct axolotl_crypto_provider { * Callback for an AES decryption implementation. * * @param output buffer to be allocated and populated with the plaintext - * @param cipher specific cipher variant to use, either AX_CIPHER_AES_CTR_NOPADDING or AX_CIPHER_AES_CBC_PKCS5 + * @param cipher specific cipher variant to use, either SG_CIPHER_AES_CTR_NOPADDING or SG_CIPHER_AES_CBC_PKCS5 * @param key the encryption key * @param key_len length of the encryption key * @param iv the initialization vector @@ -322,7 +352,7 @@ typedef struct axolotl_crypto_provider { * @param ciphertext_len length of the ciphertext * @return 0 on success, negative on failure */ - int (*decrypt_func)(axolotl_buffer **output, + int (*decrypt_func)(signal_buffer **output, int cipher, const uint8_t *key, size_t key_len, const uint8_t *iv, size_t iv_len, @@ -331,20 +361,20 @@ typedef struct axolotl_crypto_provider { /** User data pointer */ void *user_data; -} axolotl_crypto_provider; +} signal_crypto_provider; -typedef struct axolotl_session_store { +typedef struct signal_protocol_session_store { /** * Returns a copy of the serialized session record corresponding to the * provided recipient ID + device ID tuple. * * @param record pointer to a freshly allocated buffer containing the * serialized session record. Unset if no record was found. - * The axolotl library is responsible for freeing this buffer. + * The Signal Protocol library is responsible for freeing this buffer. * @param address the address of the remote client * @return 1 if the session was loaded, 0 if the session was not found, negative on failure */ - int (*load_session_func)(axolotl_buffer **record, const axolotl_address *address, void *user_data); + int (*load_session_func)(signal_buffer **record, const signal_protocol_address *address, void *user_data); /** * Returns all known devices with active sessions for a recipient @@ -354,7 +384,7 @@ typedef struct axolotl_session_store { * @param name_len the length of the name * @return size of the sessions array, or negative on failure */ - int (*get_sub_device_sessions_func)(axolotl_int_list **sessions, const char *name, size_t name_len, void *user_data); + int (*get_sub_device_sessions_func)(signal_int_list **sessions, const char *name, size_t name_len, void *user_data); /** * Commit to storage the session record for a given @@ -366,7 +396,7 @@ typedef struct axolotl_session_store { * @param record_len length of the serialized session record * @return 0 on success, negative on failure */ - int (*store_session_func)(const axolotl_address *address, uint8_t *record, size_t record_len, void *user_data); + int (*store_session_func)(const signal_protocol_address *address, uint8_t *record, size_t record_len, void *user_data); /** * Determine whether there is a committed session record for a @@ -375,7 +405,7 @@ typedef struct axolotl_session_store { * @param address the address of the remote client * @return 1 if a session record exists, 0 otherwise. */ - int (*contains_session_func)(const axolotl_address *address, void *user_data); + int (*contains_session_func)(const signal_protocol_address *address, void *user_data); /** * Remove a session record for a recipient ID + device ID tuple. @@ -383,7 +413,7 @@ typedef struct axolotl_session_store { * @param address the address of the remote client * @return 1 if a session was deleted, 0 if a session was not deleted, negative on error */ - int (*delete_session_func)(const axolotl_address *address, void *user_data); + int (*delete_session_func)(const signal_protocol_address *address, void *user_data); /** * Remove the session records corresponding to all devices of a recipient ID. @@ -402,20 +432,20 @@ typedef struct axolotl_session_store { /** User data pointer */ void *user_data; -} axolotl_session_store; +} signal_protocol_session_store; -typedef struct axolotl_pre_key_store { +typedef struct signal_protocol_pre_key_store { /** * Load a local serialized PreKey record. * * @param record pointer to a newly allocated buffer containing the record, * if found. Unset if no record was found. - * The axolotl library is responsible for freeing this buffer. + * The Signal Protocol library is responsible for freeing this buffer. * @param pre_key_id the ID of the local serialized PreKey record - * @retval AX_SUCCESS if the key was found - * @retval AX_ERR_INVALID_KEY_ID if the key could not be found + * @retval SG_SUCCESS if the key was found + * @retval SG_ERR_INVALID_KEY_ID if the key could not be found */ - int (*load_pre_key)(axolotl_buffer **record, uint32_t pre_key_id, void *user_data); + int (*load_pre_key)(signal_buffer **record, uint32_t pre_key_id, void *user_data); /** * Store a local serialized PreKey record. @@ -452,20 +482,20 @@ typedef struct axolotl_pre_key_store { /** User data pointer */ void *user_data; -} axolotl_pre_key_store; +} signal_protocol_pre_key_store; -typedef struct axolotl_signed_pre_key_store { +typedef struct signal_protocol_signed_pre_key_store { /** * Load a local serialized signed PreKey record. * * @param record pointer to a newly allocated buffer containing the record, * if found. Unset if no record was found. - * The axolotl library is responsible for freeing this buffer. + * The Signal Protocol library is responsible for freeing this buffer. * @param signed_pre_key_id the ID of the local signed PreKey record - * @retval AX_SUCCESS if the key was found - * @retval AX_ERR_INVALID_KEY_ID if the key could not be found + * @retval SG_SUCCESS if the key was found + * @retval SG_ERR_INVALID_KEY_ID if the key could not be found */ - int (*load_signed_pre_key)(axolotl_buffer **record, uint32_t signed_pre_key_id, void *user_data); + int (*load_signed_pre_key)(signal_buffer **record, uint32_t signed_pre_key_id, void *user_data); /** * Store a local serialized signed PreKey record. @@ -502,21 +532,21 @@ typedef struct axolotl_signed_pre_key_store { /** User data pointer */ void *user_data; -} axolotl_signed_pre_key_store; +} signal_protocol_signed_pre_key_store; -typedef struct axolotl_identity_key_store { +typedef struct signal_protocol_identity_key_store { /** * Get the local client's identity key pair. * * @param public_data pointer to a newly allocated buffer containing the * public key, if found. Unset if no record was found. - * The axolotl library is responsible for freeing this buffer. + * The Signal Protocol library is responsible for freeing this buffer. * @param private_data pointer to a newly allocated buffer containing the * private key, if found. Unset if no record was found. - * The axolotl library is responsible for freeing this buffer. + * The Signal Protocol library is responsible for freeing this buffer. * @return 0 on success, negative on failure */ - int (*get_identity_key_pair)(axolotl_buffer **public_data, axolotl_buffer **private_data, void *user_data); + int (*get_identity_key_pair)(signal_buffer **public_data, signal_buffer **private_data, void *user_data); /** * Return the local client's registration ID. @@ -538,13 +568,12 @@ typedef struct axolotl_identity_key_store { * from the identity store, but retain any metadata that may be kept * alongside it. * - * @param name the name of the remote client - * @param name_len the length of the name + * @param address the address of the remote client * @param key_data Pointer to the remote client's identity key, may be null * @param key_len Length of the remote client's identity key * @return 0 on success, negative on failure */ - int (*save_identity)(const char *name, size_t name_len, uint8_t *key_data, size_t key_len, void *user_data); + int (*save_identity)(const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *user_data); /** * Verify a remote client's identity key. @@ -556,14 +585,13 @@ typedef struct axolotl_identity_key_store { * store. Only if it mismatches an entry in the local store is it considered * 'untrusted.' * - * @param name the name of the remote client - * @param name_len the length of the name + * @param address the address of the remote client * @param identityKey The identity key to verify. * @param key_data Pointer to the identity key to verify * @param key_len Length of the identity key to verify * @return 1 if trusted, 0 if untrusted, negative on failure */ - int (*is_trusted_identity)(const char *name, size_t name_len, uint8_t *key_data, size_t key_len, void *user_data); + int (*is_trusted_identity)(const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *user_data); /** * Function called to perform cleanup when the data store context is being @@ -573,9 +601,9 @@ typedef struct axolotl_identity_key_store { /** User data pointer */ void *user_data; -} axolotl_identity_key_store; +} signal_protocol_identity_key_store; -typedef struct axolotl_sender_key_store { +typedef struct signal_protocol_sender_key_store { /** * Store a serialized sender key record for a given * (groupId + senderId + deviceId) tuple. @@ -585,7 +613,7 @@ typedef struct axolotl_sender_key_store { * @param record_len length of the serialized record * @return 0 on success, negative on failure */ - int (*store_sender_key)(const axolotl_sender_key_name *sender_key_name, uint8_t *record, size_t record_len, void *user_data); + int (*store_sender_key)(const signal_protocol_sender_key_name *sender_key_name, uint8_t *record, size_t record_len, void *user_data); /** * Returns a copy of the sender key record corresponding to the @@ -593,11 +621,11 @@ typedef struct axolotl_sender_key_store { * * @param record pointer to a newly allocated buffer containing the record, * if found. Unset if no record was found. - * The axolotl library is responsible for freeing this buffer. + * The Signal Protocol library is responsible for freeing this buffer. * @param sender_key_name the (groupId + senderId + deviceId) tuple * @return 1 if the record was loaded, 0 if the record was not found, negative on failure */ - int (*load_sender_key)(axolotl_buffer **record, const axolotl_sender_key_name *sender_key_name, void *user_data); + int (*load_sender_key)(signal_buffer **record, const signal_protocol_sender_key_name *sender_key_name, void *user_data); /** * Function called to perform cleanup when the data store context is being @@ -607,25 +635,25 @@ typedef struct axolotl_sender_key_store { /** User data pointer */ void *user_data; -} axolotl_sender_key_store; +} signal_protocol_sender_key_store; /** * Create a new instance of the global library context. */ -int axolotl_context_create(axolotl_context **context, void *user_data); +int signal_context_create(signal_context **context, void *user_data); /** - * Set the crypto provider to be used by the AXOLOTL library. + * Set the crypto provider to be used by the Signal Protocol library. * * @param crypto_provider Populated structure of crypto provider function * pointers. The contents of this structure are copied, so the caller * does not need to maintain its instance. * @return 0 on success, negative on failure */ -int axolotl_context_set_crypto_provider(axolotl_context *context, const axolotl_crypto_provider *crypto_provider); +int signal_context_set_crypto_provider(signal_context *context, const signal_crypto_provider *crypto_provider); /** - * Set the locking functions to be used by the AXOLOTL library for + * Set the locking functions to be used by the Signal Protocol library for * synchronization. * * Note: These functions must allow recursive locking (e.g. PTHREAD_MUTEX_RECURSIVE) @@ -634,98 +662,98 @@ int axolotl_context_set_crypto_provider(axolotl_context *context, const axolotl_ * @param unlock function to unlock a mutex * @return 0 on success, negative on failure */ -int axolotl_context_set_locking_functions(axolotl_context *context, +int signal_context_set_locking_functions(signal_context *context, void (*lock)(void *user_data), void (*unlock)(void *user_data)); /** - * Set the log function to be used by the AXOLOTL library for logging. + * Set the log function to be used by the Signal Protocol library for logging. * * @return 0 on success, negative on failure */ -int axolotl_context_set_log_function(axolotl_context *context, +int signal_context_set_log_function(signal_context *context, void (*log)(int level, const char *message, size_t len, void *user_data)); -void axolotl_context_destroy(axolotl_context *context); +void signal_context_destroy(signal_context *context); /** - * Create a new instance of the AXOLOTL data store interface. + * Create a new instance of the Signal Protocol data store interface. */ -int axolotl_store_context_create(axolotl_store_context **context, axolotl_context *global_context); +int signal_protocol_store_context_create(signal_protocol_store_context **context, signal_context *global_context); -int axolotl_store_context_set_session_store(axolotl_store_context *context, const axolotl_session_store *store); -int axolotl_store_context_set_pre_key_store(axolotl_store_context *context, const axolotl_pre_key_store *store); -int axolotl_store_context_set_signed_pre_key_store(axolotl_store_context *context, const axolotl_signed_pre_key_store *store); -int axolotl_store_context_set_identity_key_store(axolotl_store_context *context, const axolotl_identity_key_store *store); -int axolotl_store_context_set_sender_key_store(axolotl_store_context *context, const axolotl_sender_key_store *store); +int signal_protocol_store_context_set_session_store(signal_protocol_store_context *context, const signal_protocol_session_store *store); +int signal_protocol_store_context_set_pre_key_store(signal_protocol_store_context *context, const signal_protocol_pre_key_store *store); +int signal_protocol_store_context_set_signed_pre_key_store(signal_protocol_store_context *context, const signal_protocol_signed_pre_key_store *store); +int signal_protocol_store_context_set_identity_key_store(signal_protocol_store_context *context, const signal_protocol_identity_key_store *store); +int signal_protocol_store_context_set_sender_key_store(signal_protocol_store_context *context, const signal_protocol_sender_key_store *store); -void axolotl_store_context_destroy(axolotl_store_context *context); +void signal_protocol_store_context_destroy(signal_protocol_store_context *context); /* * Interface to the session store. * These functions will use the callbacks in the provided - * axolotl_store_context instance and operate in terms of higher level + * signal_protocol_store_context instance and operate in terms of higher level * library data structures. */ -int axolotl_session_load_session(axolotl_store_context *context, session_record **record, const axolotl_address *address); -int axolotl_session_get_sub_device_sessions(axolotl_store_context *context, axolotl_int_list **sessions, const char *name, size_t name_len); -int axolotl_session_store_session(axolotl_store_context *context, const axolotl_address *address, session_record *record); -int axolotl_session_contains_session(axolotl_store_context *context, const axolotl_address *address); -int axolotl_session_delete_session(axolotl_store_context *context, const axolotl_address *address); -int axolotl_session_delete_all_sessions(axolotl_store_context *context, const char *name, size_t name_len); +int signal_protocol_session_load_session(signal_protocol_store_context *context, session_record **record, const signal_protocol_address *address); +int signal_protocol_session_get_sub_device_sessions(signal_protocol_store_context *context, signal_int_list **sessions, const char *name, size_t name_len); +int signal_protocol_session_store_session(signal_protocol_store_context *context, const signal_protocol_address *address, session_record *record); +int signal_protocol_session_contains_session(signal_protocol_store_context *context, const signal_protocol_address *address); +int signal_protocol_session_delete_session(signal_protocol_store_context *context, const signal_protocol_address *address); +int signal_protocol_session_delete_all_sessions(signal_protocol_store_context *context, const char *name, size_t name_len); /* * Interface to the pre-key store. * These functions will use the callbacks in the provided - * axolotl_store_context instance and operate in terms of higher level + * signal_protocol_store_context instance and operate in terms of higher level * library data structures. */ -int axolotl_pre_key_load_key(axolotl_store_context *context, session_pre_key **pre_key, uint32_t pre_key_id); -int axolotl_pre_key_store_key(axolotl_store_context *context, session_pre_key *pre_key); -int axolotl_pre_key_contains_key(axolotl_store_context *context, uint32_t pre_key_id); -int axolotl_pre_key_remove_key(axolotl_store_context *context, uint32_t pre_key_id); +int signal_protocol_pre_key_load_key(signal_protocol_store_context *context, session_pre_key **pre_key, uint32_t pre_key_id); +int signal_protocol_pre_key_store_key(signal_protocol_store_context *context, session_pre_key *pre_key); +int signal_protocol_pre_key_contains_key(signal_protocol_store_context *context, uint32_t pre_key_id); +int signal_protocol_pre_key_remove_key(signal_protocol_store_context *context, uint32_t pre_key_id); /* * Interface to the signed pre-key store. * These functions will use the callbacks in the provided - * axolotl_store_context instance and operate in terms of higher level + * signal_protocol_store_context instance and operate in terms of higher level * library data structures. */ -int axolotl_signed_pre_key_load_key(axolotl_store_context *context, session_signed_pre_key **pre_key, uint32_t signed_pre_key_id); -int axolotl_signed_pre_key_store_key(axolotl_store_context *context, session_signed_pre_key *pre_key); -int axolotl_signed_pre_key_contains_key(axolotl_store_context *context, uint32_t signed_pre_key_id); -int axolotl_signed_pre_key_remove_key(axolotl_store_context *context, uint32_t signed_pre_key_id); +int signal_protocol_signed_pre_key_load_key(signal_protocol_store_context *context, session_signed_pre_key **pre_key, uint32_t signed_pre_key_id); +int signal_protocol_signed_pre_key_store_key(signal_protocol_store_context *context, session_signed_pre_key *pre_key); +int signal_protocol_signed_pre_key_contains_key(signal_protocol_store_context *context, uint32_t signed_pre_key_id); +int signal_protocol_signed_pre_key_remove_key(signal_protocol_store_context *context, uint32_t signed_pre_key_id); /* * Interface to the identity key store. * These functions will use the callbacks in the provided - * axolotl_store_context instance and operate in terms of higher level + * signal_protocol_store_context instance and operate in terms of higher level * library data structures. */ -int axolotl_identity_get_key_pair(axolotl_store_context *context, ratchet_identity_key_pair **key_pair); -int axolotl_identity_get_local_registration_id(axolotl_store_context *context, uint32_t *registration_id); -int axolotl_identity_save_identity(axolotl_store_context *context, const char *name, size_t name_len, ec_public_key *identity_key); -int axolotl_identity_is_trusted_identity(axolotl_store_context *context, const char *name, size_t name_len, ec_public_key *identity_key); +int signal_protocol_identity_get_key_pair(signal_protocol_store_context *context, ratchet_identity_key_pair **key_pair); +int signal_protocol_identity_get_local_registration_id(signal_protocol_store_context *context, uint32_t *registration_id); +int signal_protocol_identity_save_identity(signal_protocol_store_context *context, const signal_protocol_address *address, ec_public_key *identity_key); +int signal_protocol_identity_is_trusted_identity(signal_protocol_store_context *context, const signal_protocol_address *address, ec_public_key *identity_key); /* * Interface to the sender key store. * These functions will use the callbacks in the provided - * axolotl_store_context instance and operate in terms of higher level + * signal_protocol_store_context instance and operate in terms of higher level * library data structures. */ -int axolotl_sender_key_store_key(axolotl_store_context *context, const axolotl_sender_key_name *sender_key_name, sender_key_record *record); -int axolotl_sender_key_load_key(axolotl_store_context *context, sender_key_record **record, const axolotl_sender_key_name *sender_key_name); +int signal_protocol_sender_key_store_key(signal_protocol_store_context *context, const signal_protocol_sender_key_name *sender_key_name, sender_key_record *record); +int signal_protocol_sender_key_load_key(signal_protocol_store_context *context, sender_key_record **record, const signal_protocol_sender_key_name *sender_key_name); #ifdef __cplusplus } #endif -#endif /* AXOLOTL_H */ +#endif /* SIGNAL_PROTOCOL_H */ diff --git a/libs/libaxolotl/src/signal_protocol_internal.h b/libs/libaxolotl/src/signal_protocol_internal.h new file mode 100755 index 0000000000..de89876c00 --- /dev/null +++ b/libs/libaxolotl/src/signal_protocol_internal.h @@ -0,0 +1,87 @@ +#ifndef SIGNAL_PROTOCOL_INTERNAL_H +#define SIGNAL_PROTOCOL_INTERNAL_H + +#include "protobuf-c/protobuf-c.h" +#include "LocalStorageProtocol.pb-c.h" +#include "signal_protocol.h" + +struct signal_type_base { + unsigned int ref_count; + void (*destroy)(signal_type_base *instance); +}; + +void signal_type_init(signal_type_base *instance, + void (*destroy_func)(signal_type_base *instance)); + +#define SIGNAL_INIT(instance, destroy_func) signal_type_init((signal_type_base *)instance, destroy_func) + +struct signal_buffer { + size_t len; + uint8_t data[]; +}; + +struct signal_context { + signal_crypto_provider crypto_provider; + void (*lock)(void *user_data); + void (*unlock)(void *user_data); + void (*log)(int level, const char *message, size_t len, void *user_data); + void *user_data; +}; + +int signal_crypto_random(signal_context *context, uint8_t *data, size_t len); + +int signal_hmac_sha256_init(signal_context *context, void **hmac_context, const uint8_t *key, size_t key_len); +int signal_hmac_sha256_update(signal_context *context, void *hmac_context, const uint8_t *data, size_t data_len); +int signal_hmac_sha256_final(signal_context *context, void *hmac_context, signal_buffer **output); +void signal_hmac_sha256_cleanup(signal_context *context, void *hmac_context); + +int signal_sha512_digest_init(signal_context *context, void **digest_context); +int signal_sha512_digest_update(signal_context *context, void *digest_context, const uint8_t *data, size_t data_len); +int signal_sha512_digest_final(signal_context *context, void *digest_context, signal_buffer **output); +void signal_sha512_digest_cleanup(signal_context *context, void *digest_context); + + +int signal_encrypt(signal_context *context, + signal_buffer **output, + int cipher, + const uint8_t *key, size_t key_len, + const uint8_t *iv, size_t iv_len, + const uint8_t *plaintext, size_t plaintext_len); + +int signal_decrypt(signal_context *context, + signal_buffer **output, + int cipher, + const uint8_t *key, size_t key_len, + const uint8_t *iv, size_t iv_len, + const uint8_t *ciphertext, size_t ciphertext_len); + +void signal_lock(signal_context *context); +void signal_unlock(signal_context *context); +void signal_log(signal_context *context, int level, const char *format, ...); +void signal_explicit_bzero(void *v, size_t n); +int signal_constant_memcmp(const void *s1, const void *s2, size_t n); + +/*------------------------------------------------------------------------*/ + +/* + * Functions used for internal protocol buffers serialization support. + */ + +int ec_public_key_serialize_protobuf(ProtobufCBinaryData *buffer, const ec_public_key *key); +int ec_private_key_serialize_protobuf(ProtobufCBinaryData *buffer, const ec_private_key *key); + +int ratchet_chain_key_get_key_protobuf(const ratchet_chain_key *chain_key, ProtobufCBinaryData *buffer); +int ratchet_root_key_get_key_protobuf(const ratchet_root_key *root_key, ProtobufCBinaryData *buffer); + +int session_state_serialize_prepare(session_state *state, Textsecure__SessionStructure *session_structure); +void session_state_serialize_prepare_free(Textsecure__SessionStructure *session_structure); +int session_state_deserialize_protobuf(session_state **state, Textsecure__SessionStructure *session_structure, signal_context *global_context); + +int sender_key_state_serialize_prepare(sender_key_state *state, Textsecure__SenderKeyStateStructure *state_structure); +void sender_key_state_serialize_prepare_free(Textsecure__SenderKeyStateStructure *state_structure); +int sender_key_state_deserialize_protobuf(sender_key_state **state, Textsecure__SenderKeyStateStructure *state_structure, signal_context *global_context); + +void signal_protocol_str_serialize_protobuf(ProtobufCBinaryData *buffer, const char *str); +char *signal_protocol_str_deserialize_protobuf(ProtobufCBinaryData *buffer); + +#endif /* SIGNAL_PROTOCOL_INTERNAL_H */ diff --git a/libs/libaxolotl/src/axolotl_types.h b/libs/libaxolotl/src/signal_protocol_types.h index 9421a87c14..b45fa4c7e0 100644 --- a/libs/libaxolotl/src/axolotl_types.h +++ b/libs/libaxolotl/src/signal_protocol_types.h @@ -1,5 +1,5 @@ -#ifndef AXOLOTL_TYPES_H -#define AXOLOTL_TYPES_H +#ifndef SIGNAL_PROTOCOL_TYPES_H +#define SIGNAL_PROTOCOL_TYPES_H #include <stdint.h> #include <stdlib.h> @@ -18,38 +18,38 @@ extern "C" { /* * Base library types */ -typedef struct axolotl_type_base axolotl_type_base; -typedef struct axolotl_buffer axolotl_buffer; -typedef struct axolotl_buffer_list axolotl_buffer_list; -typedef struct axolotl_int_list axolotl_int_list; +typedef struct signal_type_base signal_type_base; +typedef struct signal_buffer signal_buffer; +typedef struct signal_buffer_list signal_buffer_list; +typedef struct signal_int_list signal_int_list; /* - * Global context for the AXOLOTL library + * Global context for the Signal Protocol library */ -typedef struct axolotl_context axolotl_context; +typedef struct signal_context signal_context; /* - * Context for the AXOLOTL data store implementation + * Context for the Signal Protocol data store implementation */ -typedef struct axolotl_store_context axolotl_store_context; +typedef struct signal_protocol_store_context signal_protocol_store_context; /* - * Address of an AXOLOTL message recipient + * Address of an Signal Protocol message recipient */ -typedef struct axolotl_address { +typedef struct signal_protocol_address { const char *name; size_t name_len; int32_t device_id; -} axolotl_address; +} signal_protocol_address; /* * A representation of a (group + sender + device) tuple */ -typedef struct axolotl_sender_key_name { +typedef struct signal_protocol_sender_key_name { const char *group_id; size_t group_id_len; - axolotl_address sender; -} axolotl_sender_key_name; + signal_protocol_address sender; +} signal_protocol_sender_key_name; /* * Curve key types @@ -57,6 +57,7 @@ typedef struct axolotl_sender_key_name { typedef struct ec_public_key ec_public_key; typedef struct ec_private_key ec_private_key; typedef struct ec_key_pair ec_key_pair; +typedef struct ec_public_key_list ec_public_key_list; /* * HKDF types @@ -66,15 +67,14 @@ typedef struct hkdf_context hkdf_context; /* * Key helper types */ -typedef struct axolotl_key_helper_pre_key_list_node axolotl_key_helper_pre_key_list_node; +typedef struct signal_protocol_key_helper_pre_key_list_node signal_protocol_key_helper_pre_key_list_node; /* * Protocol types */ -typedef struct key_exchange_message key_exchange_message; typedef struct ciphertext_message ciphertext_message; -typedef struct whisper_message whisper_message; -typedef struct pre_key_whisper_message pre_key_whisper_message; +typedef struct signal_message signal_message; +typedef struct pre_key_signal_message pre_key_signal_message; typedef struct sender_key_message sender_key_message; typedef struct sender_key_distribution_message sender_key_distribution_message; @@ -126,8 +126,16 @@ typedef struct displayable_fingerprint displayable_fingerprint; typedef struct scannable_fingerprint scannable_fingerprint; typedef struct fingerprint_generator fingerprint_generator; +/* + * Device consistency types + */ +typedef struct device_consistency_signature device_consistency_signature; +typedef struct device_consistency_commitment device_consistency_commitment; +typedef struct device_consistency_message device_consistency_message; +typedef struct device_consistency_signature_list device_consistency_signature_list; + #ifdef __cplusplus } #endif -#endif // AXOLOTL_TYPES_H +#endif /* SIGNAL_PROTOCOL_TYPES_H */ |