Implement GMAC for Takion Control Data

This commit is contained in:
Florian Märkl 2019-06-23 17:14:42 +02:00
commit 02eab4efc8
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
4 changed files with 207 additions and 57 deletions

View file

@ -80,13 +80,23 @@ typedef struct chiaki_takion_connect_info_t
void *data_cb_user; void *data_cb_user;
ChiakiTakionAVCallback av_cb; ChiakiTakionAVCallback av_cb;
void *av_cb_user; void *av_cb_user;
bool enable_crypt;
} ChiakiTakionConnectInfo; } ChiakiTakionConnectInfo;
typedef enum chiaki_takion_crypt_mode_t {
CHIAKI_TAKION_CRYPT_MODE_NO_CRYPT, // encryption disabled completely, for Senkusha
CHIAKI_TAKION_CRYPT_MODE_PRE_CRYPT, // encryption required, but not yet initialized (during handshake)
CHIAKI_TAKION_CRYPT_MODE_CRYPT // encryption required
} ChiakiTakionCryptMode;
typedef struct chiaki_takion_t typedef struct chiaki_takion_t
{ {
ChiakiLog *log; ChiakiLog *log;
ChiakiTakionCryptMode crypt_mode;
ChiakiGKCrypt *gkcrypt_local; // if NULL (default), no gmac is calculated and nothing is encrypted ChiakiGKCrypt *gkcrypt_local; // if NULL (default), no gmac is calculated and nothing is encrypted
size_t key_pos_local; size_t key_pos_local;
ChiakiMutex gkcrypt_local_mutex; ChiakiMutex gkcrypt_local_mutex;
@ -111,15 +121,45 @@ typedef struct chiaki_takion_t
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, ChiakiTakionConnectInfo *info); CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, ChiakiTakionConnectInfo *info);
CHIAKI_EXPORT void chiaki_takion_close(ChiakiTakion *takion); CHIAKI_EXPORT void chiaki_takion_close(ChiakiTakion *takion);
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, uint8_t *buf, size_t buf_size);
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *takion, uint32_t key_pos, uint8_t *gmac, uint8_t type_b, uint16_t channel, uint8_t *buf, size_t buf_size);
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet);
static inline void chiaki_takion_set_crypt(ChiakiTakion *takion, ChiakiGKCrypt *gkcrypt_local, ChiakiGKCrypt *gkcrypt_remote) { static inline void chiaki_takion_set_crypt(ChiakiTakion *takion, ChiakiGKCrypt *gkcrypt_local, ChiakiGKCrypt *gkcrypt_remote) {
takion->gkcrypt_local = gkcrypt_local; takion->gkcrypt_local = gkcrypt_local;
takion->gkcrypt_remote = gkcrypt_remote; takion->gkcrypt_remote = gkcrypt_remote;
} }
/**
* Get a new key pos and advance by data_size.
*
* Thread-safe while Takion is running.
* @param key_pos pointer to write the new key pos to. will be 0 if encryption is disabled. Contents undefined on failure.
*/
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_crypt_advance_key_pos(ChiakiTakion *takion, size_t data_size, size_t *key_pos);
/**
* Send a datagram directly on the socket.
*
* Thread-safe while Takion is running.
*/
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, const uint8_t *buf, size_t buf_size);
/**
* Calculate the MAC for the packet depending on the type derived from the first byte in buf,
* assign MAC inside buf at the respective position and send the packet.
*
* If encryption is disabled, the MAC will be set to 0.
*/
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t *buf, size_t buf_size);
/**
* Thread-safe while Takion is running.
*/
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *takion, uint8_t type_b, uint16_t channel, uint8_t *buf, size_t buf_size);
/**
* Thread-safe while Takion is running.
*/
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet);
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t base_type, uint8_t *buf, size_t buf_size); CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t base_type, uint8_t *buf, size_t buf_size);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -177,7 +177,7 @@ static ChiakiErrorCode senkusha_send_big(Senkusha *senkusha)
} }
buf_size = stream.bytes_written; buf_size = stream.bytes_written;
ChiakiErrorCode err = chiaki_takion_send_message_data(&senkusha->takion, 0, NULL, 1, 1, buf, buf_size); ChiakiErrorCode err = chiaki_takion_send_message_data(&senkusha->takion, 1, 1, buf, buf_size);
return err; return err;
} }
@ -204,7 +204,7 @@ static ChiakiErrorCode senkusha_send_disconnect(Senkusha *senkusha)
} }
buf_size = stream.bytes_written; buf_size = stream.bytes_written;
ChiakiErrorCode err = chiaki_takion_send_message_data(&senkusha->takion, 0, NULL, 1, 1, buf, buf_size); ChiakiErrorCode err = chiaki_takion_send_message_data(&senkusha->takion, 1, 1, buf, buf_size);
return err; return err;
} }

View file

@ -252,6 +252,9 @@ static void stream_connection_takion_data(ChiakiTakionMessageDataType data_type,
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_ERROR, buf, buf_size); chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_ERROR, buf, buf_size);
return; return;
} }
CHIAKI_LOGD(stream_connection->log, "StreamConnection received data\n");
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_DEBUG, buf, buf_size);
} }
static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size) static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size)
@ -525,7 +528,7 @@ static ChiakiErrorCode stream_connection_send_big(ChiakiStreamConnection *stream
} }
buf_size = stream.bytes_written; buf_size = stream.bytes_written;
err = chiaki_takion_send_message_data(&stream_connection->takion, 0, 0, 1, 1, buf, buf_size); err = chiaki_takion_send_message_data(&stream_connection->takion, 1, 1, buf, buf_size);
return err; return err;
} }
@ -548,7 +551,7 @@ static ChiakiErrorCode stream_connection_send_streaminfo_ack(ChiakiStreamConnect
} }
buf_size = stream.bytes_written; buf_size = stream.bytes_written;
return chiaki_takion_send_message_data(&stream_connection->takion, 0, NULL, 1, 9, buf, buf_size); return chiaki_takion_send_message_data(&stream_connection->takion, 1, 9, buf, buf_size);
} }
static ChiakiErrorCode stream_connection_send_disconnect(ChiakiStreamConnection *stream_connection) static ChiakiErrorCode stream_connection_send_disconnect(ChiakiStreamConnection *stream_connection)
@ -573,7 +576,7 @@ static ChiakiErrorCode stream_connection_send_disconnect(ChiakiStreamConnection
} }
buf_size = stream.bytes_written; buf_size = stream.bytes_written;
ChiakiErrorCode err = chiaki_takion_send_message_data(&stream_connection->takion, 0, 0 /* TODO: gmac? */,1, 1, buf, buf_size); ChiakiErrorCode err = chiaki_takion_send_message_data(&stream_connection->takion, 1, 1, buf, buf_size);
return err; return err;
} }
@ -632,19 +635,5 @@ static ChiakiErrorCode stream_connection_send_heartbeat(ChiakiStreamConnection *
return CHIAKI_ERR_UNKNOWN; return CHIAKI_ERR_UNKNOWN;
} }
size_t buf_size = stream.bytes_written; return chiaki_takion_send_message_data(&stream_connection->takion, 1, 1, buf, stream.bytes_written);
uint8_t gmac[CHIAKI_GKCRYPT_GMAC_SIZE];
uint32_t key_pos;
ChiakiErrorCode err = chiaki_mutex_lock(&stream_connection->takion.gkcrypt_local_mutex);
if(err != CHIAKI_ERR_SUCCESS)
return err;
key_pos = stream_connection->takion.key_pos_local;
err = chiaki_gkcrypt_gmac(stream_connection->takion.gkcrypt_local, key_pos, buf, buf_size, gmac);
stream_connection->takion.key_pos_local += buf_size;
chiaki_mutex_unlock(&stream_connection->takion.gkcrypt_local_mutex);
if(err != CHIAKI_ERR_SUCCESS)
return err;
return chiaki_takion_send_message_data(&stream_connection->takion, key_pos, gmac, 1, 1, buf, buf_size);
} }

View file

@ -27,14 +27,59 @@
#include <assert.h> #include <assert.h>
/**
* Base type of Takion packets. Lower nibble of the first byte in datagrams.
*/
typedef enum takion_packet_type_t { typedef enum takion_packet_type_t {
TAKION_PACKET_TYPE_MESSAGE = 0, TAKION_PACKET_TYPE_CONTROL = 0,
TAKION_PACKET_TYPE_FEEDBACK_HISTORY = 1,
TAKION_PACKET_TYPE_VIDEO = 2, TAKION_PACKET_TYPE_VIDEO = 2,
TAKION_PACKET_TYPE_AUDIO = 3, TAKION_PACKET_TYPE_AUDIO = 3,
TAKION_PACKET_TYPE_HANDSHAKE = 4,
TAKION_PACKET_TYPE_CONGESTION = 5,
TAKION_PACKET_TYPE_FEEDBACK_STATE = 6,
TAKION_PACKET_TYPE_RUMBLE_EVENT = 7,
TAKION_PACKET_TYPE_CLIENT_INFO = 8,
TAKION_PACKET_TYPE_PAD_INFO_EVENT = 9
} TakionPacketType; } TakionPacketType;
/**
* @return The offset of the mac of size CHIAKI_GKCRYPT_GMAC_SIZE inside a packet of type or -1 if unknown.
*/
ssize_t takion_packet_type_mac_offset(TakionPacketType type)
{
switch(type)
{
case TAKION_PACKET_TYPE_CONTROL:
return 5;
case TAKION_PACKET_TYPE_VIDEO:
case TAKION_PACKET_TYPE_AUDIO:
return 0xa;
default:
return -1;
}
}
/**
* @return The offset of the 4-byte key_pos inside a packet of type or -1 if unknown.
*/
ssize_t takion_packet_type_key_pos_offset(TakionPacketType type)
{
switch(type)
{
case TAKION_PACKET_TYPE_CONTROL:
return 0x9;
case TAKION_PACKET_TYPE_VIDEO:
case TAKION_PACKET_TYPE_AUDIO:
return 0xe;
default:
return -1;
}
}
typedef uint32_t TakionPacketKeyPos;
// TODO: find out what these are // TODO: find out what these are
#define TAKION_LOCAL_SOMETHING 0x19000 #define TAKION_LOCAL_SOMETHING 0x19000
@ -94,7 +139,7 @@ static void takion_handle_packet_message(ChiakiTakion *takion, uint8_t *buf, siz
static void takion_handle_packet_message_data(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size); static void takion_handle_packet_message_data(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size);
static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size); static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size);
static ChiakiErrorCode takion_parse_message(ChiakiTakion *takion, uint8_t *buf, size_t buf_size, TakionMessage *msg); static ChiakiErrorCode takion_parse_message(ChiakiTakion *takion, uint8_t *buf, size_t buf_size, TakionMessage *msg);
static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint8_t *mac, uint32_t key_pos, uint8_t type_a, uint8_t type_b, size_t payload_data_size); static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint32_t key_pos, uint8_t type_a, uint8_t type_b, size_t payload_data_size);
static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMessagePayloadInit *payload); static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMessagePayloadInit *payload);
static ChiakiErrorCode takion_send_message_cookie(ChiakiTakion *takion, uint8_t *cookie); static ChiakiErrorCode takion_send_message_cookie(ChiakiTakion *takion, uint8_t *cookie);
static ChiakiErrorCode takion_recv(ChiakiTakion *takion, uint8_t *buf, size_t *buf_size, struct timeval *timeout); static ChiakiErrorCode takion_recv(ChiakiTakion *takion, uint8_t *buf, size_t *buf_size, struct timeval *timeout);
@ -126,6 +171,8 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, Chiaki
takion->recv_timeout.tv_usec = 0; takion->recv_timeout.tv_usec = 0;
takion->send_retries = 5; takion->send_retries = 5;
takion->crypt_mode = info->enable_crypt ? CHIAKI_TAKION_CRYPT_MODE_PRE_CRYPT : CHIAKI_TAKION_CRYPT_MODE_NO_CRYPT;
CHIAKI_LOGI(takion->log, "Takion connecting\n"); CHIAKI_LOGI(takion->log, "Takion connecting\n");
ChiakiErrorCode err = chiaki_stop_pipe_init(&takion->stop_pipe); ChiakiErrorCode err = chiaki_stop_pipe_init(&takion->stop_pipe);
@ -258,28 +305,99 @@ CHIAKI_EXPORT void chiaki_takion_close(ChiakiTakion *takion)
chiaki_stop_pipe_fini(&takion->stop_pipe); chiaki_stop_pipe_fini(&takion->stop_pipe);
} }
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, uint8_t *buf, size_t buf_size) CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_crypt_advance_key_pos(ChiakiTakion *takion, size_t data_size, size_t *key_pos)
{ {
//CHIAKI_LOGD(takion->log, "Takion send:\n"); ChiakiErrorCode err = chiaki_mutex_lock(&takion->gkcrypt_local_mutex);
//chiaki_log_hexdump(takion->log, CHIAKI_LOG_DEBUG, buf, buf_size); if(err != CHIAKI_ERR_SUCCESS)
return err;
if(takion->gkcrypt_local)
{
size_t cur = takion->key_pos_local;
if(SIZE_MAX - cur < data_size)
{
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
return CHIAKI_ERR_OVERFLOW;
}
*key_pos = cur;
takion->key_pos_local = cur + data_size;
}
else
*key_pos = 0;
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
return CHIAKI_ERR_SUCCESS;
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, const uint8_t *buf, size_t buf_size)
{
ssize_t r = send(takion->sock, buf, buf_size, 0); ssize_t r = send(takion->sock, buf, buf_size, 0);
if(r < 0) if(r < 0)
return CHIAKI_ERR_NETWORK; return CHIAKI_ERR_NETWORK;
return CHIAKI_ERR_SUCCESS; return CHIAKI_ERR_SUCCESS;
} }
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *takion, uint32_t key_pos, uint8_t *gmac, uint8_t type_b, uint16_t channel, uint8_t *buf, size_t buf_size) CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t *buf, size_t buf_size)
{
if(buf_size < 1)
{
CHIAKI_LOGE(takion->log, "Takion send buf too small\n");
return CHIAKI_ERR_BUF_TOO_SMALL;
}
TakionPacketType base_type = buf[0] & 0xf;
ssize_t mac_offset = takion_packet_type_mac_offset(base_type);
ssize_t key_pos_offset = takion_packet_type_key_pos_offset(base_type);
if(mac_offset < 0 || key_pos_offset < 0)
{
CHIAKI_LOGE(takion->log, "Invalid Takion packet type for mac and key pos offset\n");
return CHIAKI_ERR_INVALID_DATA;
}
if(buf_size < mac_offset + CHIAKI_GKCRYPT_GMAC_SIZE || buf_size < key_pos_offset + sizeof(TakionPacketKeyPos))
{
CHIAKI_LOGE(takion->log, "Takion send buf too small for mac and key pos\n");
return CHIAKI_ERR_BUF_TOO_SMALL;
}
ChiakiErrorCode err = chiaki_mutex_lock(&takion->gkcrypt_local_mutex);
if(err != CHIAKI_ERR_SUCCESS)
return err;
memset(buf + mac_offset, 0, CHIAKI_GKCRYPT_GMAC_SIZE);
if(takion->gkcrypt_local)
{
TakionPacketKeyPos key_pos = htonl(*((TakionPacketKeyPos *)(buf + key_pos_offset)));
chiaki_gkcrypt_gmac(takion->gkcrypt_local, key_pos, buf, buf_size, buf + mac_offset);
}
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
CHIAKI_LOGD(takion->log, "Takion sending:\n");
chiaki_log_hexdump_raw(takion->log, CHIAKI_LOG_DEBUG, buf, buf_size);
return chiaki_takion_send_raw(takion, buf, buf_size);
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *takion, uint8_t type_b, uint16_t channel, uint8_t *buf, size_t buf_size)
{ {
// TODO: can we make this more memory-efficient? // TODO: can we make this more memory-efficient?
// TODO: split packet if necessary? // TODO: split packet if necessary?
size_t key_pos;
ChiakiErrorCode err = chiaki_takion_crypt_advance_key_pos(takion, buf_size, &key_pos);
if(err != CHIAKI_ERR_SUCCESS)
return err;
size_t packet_size = 1 + MESSAGE_HEADER_SIZE + 9 + buf_size; size_t packet_size = 1 + MESSAGE_HEADER_SIZE + 9 + buf_size;
uint8_t *packet_buf = malloc(packet_size); uint8_t *packet_buf = malloc(packet_size);
if(!packet_buf) if(!packet_buf)
return CHIAKI_ERR_MEMORY; return CHIAKI_ERR_MEMORY;
packet_buf[0] = TAKION_PACKET_TYPE_MESSAGE; packet_buf[0] = TAKION_PACKET_TYPE_CONTROL;
takion_write_message_header(packet_buf + 1, takion->tag_remote, gmac, key_pos, TAKION_MESSAGE_TYPE_A_DATA, type_b, 9 + buf_size);
takion_write_message_header(packet_buf + 1, takion->tag_remote, key_pos, TAKION_MESSAGE_TYPE_A_DATA, type_b, 9 + buf_size);
uint8_t *msg_payload = packet_buf + 1 + MESSAGE_HEADER_SIZE; uint8_t *msg_payload = packet_buf + 1 + MESSAGE_HEADER_SIZE;
*((uint32_t *)(msg_payload + 0)) = htonl(takion->seq_num_local++); *((uint32_t *)(msg_payload + 0)) = htonl(takion->seq_num_local++);
@ -289,16 +407,22 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *taki
memcpy(msg_payload + 9, buf, buf_size); memcpy(msg_payload + 9, buf, buf_size);
// TODO: instead of just sending and forgetting about it, make sure to receive data ack, resend if necessary, etc. // TODO: instead of just sending and forgetting about it, make sure to receive data ack, resend if necessary, etc.
ChiakiErrorCode err = chiaki_takion_send_raw(takion, packet_buf, packet_size); err = chiaki_takion_send(takion, packet_buf, packet_size);
free(packet_buf); free(packet_buf);
return err; return err;
} }
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data_ack(ChiakiTakion *takion, uint32_t key_pos, uint8_t type_b, uint16_t channel, uint32_t seq_num) CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data_ack(ChiakiTakion *takion, uint8_t type_b, uint16_t channel, uint32_t seq_num)
{ {
uint8_t buf[1 + MESSAGE_HEADER_SIZE + 0xc]; uint8_t buf[1 + MESSAGE_HEADER_SIZE + 0xc];
buf[0] = TAKION_PACKET_TYPE_MESSAGE; buf[0] = TAKION_PACKET_TYPE_CONTROL;
takion_write_message_header(buf + 1, takion->tag_remote, NULL, 0, TAKION_MESSAGE_TYPE_A_DATA_ACK, 0, 0xc);
size_t key_pos;
ChiakiErrorCode err = chiaki_takion_crypt_advance_key_pos(takion, sizeof(buf), &key_pos);
if(err != CHIAKI_ERR_SUCCESS)
return err;
takion_write_message_header(buf + 1, takion->tag_remote, key_pos, TAKION_MESSAGE_TYPE_A_DATA_ACK, type_b, 0xc);
uint8_t *data_ack = buf + 1 + MESSAGE_HEADER_SIZE; uint8_t *data_ack = buf + 1 + MESSAGE_HEADER_SIZE;
*((uint32_t *)(data_ack + 0)) = htonl(seq_num); *((uint32_t *)(data_ack + 0)) = htonl(seq_num);
@ -306,14 +430,14 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data_ack(ChiakiTakion *
*((uint16_t *)(data_ack + 8)) = 0; *((uint16_t *)(data_ack + 8)) = 0;
*((uint16_t *)(data_ack + 0xa)) = 0; *((uint16_t *)(data_ack + 0xa)) = 0;
return chiaki_takion_send_raw(takion, buf, sizeof(buf)); return chiaki_takion_send(takion, buf, sizeof(buf));
} }
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet) CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet)
{ {
uint8_t buf[0xf]; uint8_t buf[0xf];
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
buf[0] = 5; buf[0] = TAKION_PACKET_TYPE_CONGESTION;
*((uint16_t *)(buf + 1)) = htons(packet->word_0); *((uint16_t *)(buf + 1)) = htons(packet->word_0);
*((uint16_t *)(buf + 3)) = htons(packet->word_1); *((uint16_t *)(buf + 3)) = htons(packet->word_1);
*((uint16_t *)(buf + 5)) = htons(packet->word_2); *((uint16_t *)(buf + 5)) = htons(packet->word_2);
@ -393,7 +517,7 @@ static ChiakiErrorCode takion_handle_packet_mac(ChiakiTakion *takion, uint8_t ba
size_t key_pos_offset; size_t key_pos_offset;
switch(base_type) switch(base_type)
{ {
case TAKION_PACKET_TYPE_MESSAGE: case TAKION_PACKET_TYPE_CONTROL:
mac_offset = 5; mac_offset = 5;
key_pos_offset = 0x9; key_pos_offset = 0x9;
break; break;
@ -403,7 +527,7 @@ static ChiakiErrorCode takion_handle_packet_mac(ChiakiTakion *takion, uint8_t ba
key_pos_offset = 0xe; key_pos_offset = 0xe;
break; break;
default: default:
CHIAKI_LOGW(takion->log, "Takion packet with unknown type %#x received\n", base_type); CHIAKI_LOGW(takion->log, "Takion packet with unknown type (for gmac) %#x received\n", base_type);
//chiaki_log_hexdump(takion->log, CHIAKI_LOG_WARNING, buf, buf_size); //chiaki_log_hexdump(takion->log, CHIAKI_LOG_WARNING, buf, buf_size);
return CHIAKI_ERR_INVALID_DATA; return CHIAKI_ERR_INVALID_DATA;
} }
@ -414,7 +538,7 @@ static ChiakiErrorCode takion_handle_packet_mac(ChiakiTakion *takion, uint8_t ba
} }
uint32_t key_pos = ntohl(*((uint32_t *)(buf + key_pos_offset))); uint32_t key_pos = ntohl(*((uint32_t *)(buf + key_pos_offset)));
if(base_type == TAKION_PACKET_TYPE_MESSAGE) if(base_type == TAKION_PACKET_TYPE_CONTROL)
memset(buf + key_pos_offset, 0, sizeof(uint32_t)); memset(buf + key_pos_offset, 0, sizeof(uint32_t));
uint8_t mac[CHIAKI_GKCRYPT_GMAC_SIZE]; uint8_t mac[CHIAKI_GKCRYPT_GMAC_SIZE];
@ -458,7 +582,7 @@ static void takion_handle_packet(ChiakiTakion *takion, uint8_t *buf, size_t buf_
switch(base_type) switch(base_type)
{ {
case TAKION_PACKET_TYPE_MESSAGE: case TAKION_PACKET_TYPE_CONTROL:
takion_handle_packet_message(takion, buf, buf_size); takion_handle_packet_message(takion, buf, buf_size);
break; break;
case TAKION_PACKET_TYPE_VIDEO: case TAKION_PACKET_TYPE_VIDEO:
@ -525,7 +649,7 @@ static void takion_handle_packet_message_data(ChiakiTakion *takion, uint8_t type
takion->data_cb((ChiakiTakionMessageDataType)data_type, data, data_size, takion->data_cb_user); takion->data_cb((ChiakiTakionMessageDataType)data_type, data, data_size, takion->data_cb_user);
} }
chiaki_takion_send_message_data_ack(takion, 0, 0, channel, seq_num); chiaki_takion_send_message_data_ack(takion, 0, channel, seq_num);
} }
static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size) static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t type_b, uint8_t *buf, size_t buf_size)
@ -563,12 +687,9 @@ static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t
* *
* @param raw_payload_size size of the actual data of the payload excluding type_a, type_b and payload_size * @param raw_payload_size size of the actual data of the payload excluding type_a, type_b and payload_size
*/ */
static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint8_t *mac, uint32_t key_pos, uint8_t type_a, uint8_t type_b, size_t payload_data_size) static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint32_t key_pos, uint8_t type_a, uint8_t type_b, size_t payload_data_size)
{ {
*((uint32_t *)(buf + 0)) = htonl(tag); *((uint32_t *)(buf + 0)) = htonl(tag);
if(mac)
memcpy(buf + 4, mac, CHIAKI_GKCRYPT_GMAC_SIZE);
else
memset(buf + 4, 0, CHIAKI_GKCRYPT_GMAC_SIZE); memset(buf + 4, 0, CHIAKI_GKCRYPT_GMAC_SIZE);
*((uint32_t *)(buf + 8)) = htonl(key_pos); *((uint32_t *)(buf + 8)) = htonl(key_pos);
*(buf + 0xc) = type_a; *(buf + 0xc) = type_a;
@ -616,8 +737,8 @@ static ChiakiErrorCode takion_parse_message(ChiakiTakion *takion, uint8_t *buf,
static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMessagePayloadInit *payload) static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMessagePayloadInit *payload)
{ {
uint8_t message[1 + MESSAGE_HEADER_SIZE + 0x10]; uint8_t message[1 + MESSAGE_HEADER_SIZE + 0x10];
message[0] = TAKION_PACKET_TYPE_MESSAGE; message[0] = TAKION_PACKET_TYPE_CONTROL;
takion_write_message_header(message + 1, takion->tag_remote, NULL, 0, TAKION_MESSAGE_TYPE_A_INIT, 0, 0x10); takion_write_message_header(message + 1, takion->tag_remote, 0, TAKION_MESSAGE_TYPE_A_INIT, 0, 0x10);
uint8_t *pl = message + 1 + MESSAGE_HEADER_SIZE; uint8_t *pl = message + 1 + MESSAGE_HEADER_SIZE;
*((uint32_t *)(pl + 0)) = htonl(payload->tag0); *((uint32_t *)(pl + 0)) = htonl(payload->tag0);
@ -634,8 +755,8 @@ static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMess
static ChiakiErrorCode takion_send_message_cookie(ChiakiTakion *takion, uint8_t *cookie) static ChiakiErrorCode takion_send_message_cookie(ChiakiTakion *takion, uint8_t *cookie)
{ {
uint8_t message[1 + MESSAGE_HEADER_SIZE + TAKION_COOKIE_SIZE]; uint8_t message[1 + MESSAGE_HEADER_SIZE + TAKION_COOKIE_SIZE];
message[0] = TAKION_PACKET_TYPE_MESSAGE; message[0] = TAKION_PACKET_TYPE_CONTROL;
takion_write_message_header(message + 1, takion->tag_remote, NULL, 0, TAKION_MESSAGE_TYPE_A_COOKIE, 0, TAKION_COOKIE_SIZE); takion_write_message_header(message + 1, takion->tag_remote, 0, TAKION_MESSAGE_TYPE_A_COOKIE, 0, TAKION_COOKIE_SIZE);
memcpy(message + 1 + MESSAGE_HEADER_SIZE, cookie, TAKION_COOKIE_SIZE); memcpy(message + 1 + MESSAGE_HEADER_SIZE, cookie, TAKION_COOKIE_SIZE);
return chiaki_takion_send_raw(takion, message, sizeof(message)); return chiaki_takion_send_raw(takion, message, sizeof(message));
} }
@ -656,9 +777,9 @@ static ChiakiErrorCode takion_recv_message_init_ack(ChiakiTakion *takion, Takion
return CHIAKI_ERR_INVALID_RESPONSE; return CHIAKI_ERR_INVALID_RESPONSE;
} }
if(message[0] != TAKION_PACKET_TYPE_MESSAGE) if(message[0] != TAKION_PACKET_TYPE_CONTROL)
{ {
CHIAKI_LOGE(takion->log, "Takion received packet of type %#x while expecting init ack message with type %#x\n", message[0], TAKION_PACKET_TYPE_MESSAGE); CHIAKI_LOGE(takion->log, "Takion received packet of type %#x while expecting init ack message with type %#x\n", message[0], TAKION_PACKET_TYPE_CONTROL);
return CHIAKI_ERR_INVALID_RESPONSE; return CHIAKI_ERR_INVALID_RESPONSE;
} }
@ -704,9 +825,9 @@ static ChiakiErrorCode takion_recv_message_cookie_ack(ChiakiTakion *takion)
return CHIAKI_ERR_INVALID_RESPONSE; return CHIAKI_ERR_INVALID_RESPONSE;
} }
if(message[0] != TAKION_PACKET_TYPE_MESSAGE) if(message[0] != TAKION_PACKET_TYPE_CONTROL)
{ {
CHIAKI_LOGE(takion->log, "Takion received packet of type %#x while expecting cookie ack message with type %#x\n", message[0], TAKION_PACKET_TYPE_MESSAGE); CHIAKI_LOGE(takion->log, "Takion received packet of type %#x while expecting cookie ack message with type %#x\n", message[0], TAKION_PACKET_TYPE_CONTROL);
return CHIAKI_ERR_INVALID_RESPONSE; return CHIAKI_ERR_INVALID_RESPONSE;
} }