From a8cf3c831fb50ccdafa3218977a6aa749e38b02d Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Sun, 25 Sep 2011 11:18:03 +0200 Subject: [WIP] Add support for transporting audio data using udp --- src/Makefile.am | 6 +- src/cmumble.c | 46 ++++---- src/cmumble.h | 8 ++ src/connection.c | 157 ++++++++++++++++++++++++++- src/connection.h | 9 ++ src/crypt.c | 319 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/crypt.h | 80 ++++++++++++++ 7 files changed, 600 insertions(+), 25 deletions(-) create mode 100644 src/crypt.c create mode 100644 src/crypt.h diff --git a/src/Makefile.am b/src/Makefile.am index 6946330..4c063c3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,15 +3,15 @@ SUBDIRS = ocb bin_PROGRAMS = cmumble noinst_HEADERS = cmumble.h message.h varint.h io.h \ - connection.h audio.h commands.h util.h + connection.h audio.h commands.h util.h crypt.h nodist_noinst_HEADERS = mumble.pb-c.h message_list.h cmumble_SOURCES = cmumble.c message.c varint.c io.c \ - connection.c audio.c commands.c util.c + connection.c audio.c commands.c util.c crypt.c nodist_cmumble_SOURCES = mumble.pb-c.c cmumble_LDADD = $(PROTOBUF_LIBS) $(GLIB_LIBS) $(GIO_LIBS) \ - $(GSTREAMER_LIBS) $(CELT_LIBS) \ + $(GSTREAMER_LIBS) $(CELT_LIBS) -lssl\ ocb/libocb.a AM_CPPFLAGS = $(PROTOBUF_CFLAGS) $(GLIB_CFLAGS) $(GIO_CFLAGS) \ $(GSTREAMER_CFLAGS) $(CELT_CFLAGS) diff --git a/src/cmumble.c b/src/cmumble.c index e76920e..dea3de9 100644 --- a/src/cmumble.c +++ b/src/cmumble.c @@ -98,28 +98,32 @@ recv_server_sync(MumbleProto__ServerSync *sync, struct cmumlbe *cm) static void recv_crypt_setup(MumbleProto__CryptSetup *crypt, struct cmumlbe *cm) { -#if 0 - int i; - - if (crypt->has_key) { - g_print("key: 0x"); - for (i = 0; i < crypt->key.len; ++i) - g_print("%x", crypt->key.data[i]); - g_print("\n"); - } - if (crypt->has_client_nonce) { - g_print("client nonce: 0x"); - for (i = 0; i < crypt->client_nonce.len; ++i) - g_print("%x", crypt->client_nonce.data[i]); - g_print("\n"); - } - if (crypt->has_server_nonce) { - g_print("server nonce: 0x"); - for (i = 0; i < crypt->server_nonce.len; ++i) - g_print("%x", crypt->server_nonce.data[i]); - g_print("\n"); - } + /* FIXME: require all data lengths to be 16? */ + + if (crypt->key.len != 16 || crypt->client_nonce.len != 16 || + crypt->server_nonce.len != 16) + return; + + cm->ocb_key = g_memdup(crypt->key.data, + crypt->key.len); + cm->ocb_client_nonce = g_memdup(crypt->client_nonce.data, + crypt->client_nonce.len); + cm->ocb_server_nonce = g_memdup(crypt->server_nonce.data, + crypt->server_nonce.len); + +#if 1 + cm->ocb = ocb_aes_init(cm->ocb_key, 3, NULL); + g_assert(cm->ocb); #endif +#if 1 + CryptState_init(&cm->crypt); + CryptState_setKey(&cm->crypt, + cm->ocb_key, + cm->ocb_client_nonce, + cm->ocb_server_nonce); +#endif + + cmumble_connection_udp_init(cm); } static void diff --git a/src/cmumble.h b/src/cmumble.h index cc40149..0b03497 100644 --- a/src/cmumble.h +++ b/src/cmumble.h @@ -11,6 +11,9 @@ #include "connection.h" #include "audio.h" #include "commands.h" +#include "ocb/ocb.h" + +#include "crypt.h" typedef void (*callback_t)(ProtobufCMessage *msg, struct cmumlbe *); @@ -34,6 +37,11 @@ struct cmumlbe { GList *channels; struct cmumble_user *user; + keystruct *ocb; + cryptState_t crypt; + guchar *ocb_key; + guchar *ocb_client_nonce; + guchar *ocb_server_nonce; }; struct cmumble_user { diff --git a/src/connection.c b/src/connection.c index 7fefdb3..5bc5341 100644 --- a/src/connection.c +++ b/src/connection.c @@ -3,6 +3,7 @@ #include "connection.h" #include "cmumble.h" +#include "varint.h" static gboolean read_cb(GObject *pollable_stream, gpointer data) @@ -18,6 +19,161 @@ read_cb(GObject *pollable_stream, gpointer data) return TRUE; } +static gboolean +read_udp(GSocket *socket, GIOCondition condition, gpointer user_data) +{ + GError *error = NULL; + gchar buf[1024]; + gssize size = 0; + + size = g_socket_receive(socket, buf, sizeof(buf), NULL, &error); + + g_print("got udp data: %ld\n", size); + + return TRUE; +} + +#if 0 +static void +print_hex(char *hex, int num) +{ + int i; + + for (i = 0; i < num; ++i) + printf("%02x", hex[i] & 0xff); + +} +#endif + +static void +do_udp_ping(struct cmumlbe *cm) +{ + uint8_t data[16]; + uint32_t write = 0, pos = 0; + GTimeVal tv; + GError *error = NULL; + gssize sent; + + g_get_current_time(&tv); + + data[pos++] = (udp_ping << 5); + encode_varint(&data[pos], &write, tv.tv_sec, 16-pos); + pos += write; + + char foo[16] = { 0 }; +#if 0 + int i; + char tag[16] = { 0 }; + char bar[16] = { 0 }; + char ha[16] = {0}; + +#if 1 + /* Increase nonce, see: + * http://www.cs.ucdavis.edu/~rogaway/ocb/ocb-back.htm#nonce */ + for (i = 0; i < 16; ++i) + if (++cm->ocb_client_nonce[i]) + break; +#endif + + g_assert(CryptState_isValid(&cm->crypt)); + +#if 1 + bar[0] = cm->ocb_client_nonce[0]; + ocb_aes_encrypt(cm->ocb, cm->ocb_client_nonce, + data, pos, + bar+4, bar+1); + + ha[0] = cm->ocb_client_nonce[0]; + ocb_aes_encrypt(cm->ocb, cm->ocb_client_nonce, + data, pos, + ha+4, ha+1); +#endif +#endif +#if 1 + CryptState_encrypt(&cm->crypt, + data, (uint8_t *) foo, pos); +#endif + +#if 0 + printf("\n"); + printf("nonce: 0x"); + print_hex(cm->ocb_client_nonce, 16); + printf("\n"); + + printf("tag: 0x"); + print_hex(tag, 3); + printf("\n"); + + printf("data: 0x"); + print_hex((char *)data, pos); + printf("\n"); + + printf("foo: 0x"); + print_hex(foo, pos+4); + printf("\n"); + printf("foo decrypted: 0x"); + uint8_t lo[16], tag2[16]; + CryptState_ocb_decrypt(&cm->crypt, (uint8_t *) foo+4, (uint8_t *) lo, pos, cm->ocb_client_nonce, tag2); + print_hex(lo, pos); + printf("\n"); + printf("decrypted tag: 0x"); + print_hex(tag2, 3); + printf("\n"); + + printf("bar: 0x"); + print_hex(bar, pos+4); + printf("\n"); + printf("ha: 0x"); + print_hex(ha, pos+4); + printf("\n"); + + printf("length: %d\n", pos); + + //memset(tag, 0, 128); +#endif + +#if 0 + ocb_aes_decrypt(cm->ocb, cm->ocb_client_nonce, + foo+4, pos, + bar, tag); + + printf("decrypt: 0x"); + print_hex(bar, pos); + printf("\n"); +#endif + + sent = g_socket_send(cm->con.udp.sock, foo, pos+4, NULL, &error); + + g_print("udp sent: %ld\n", sent); +} + +void +cmumble_connection_udp_init(struct cmumlbe *cm) +{ + GError *error = NULL; + + cm->con.udp.connected = FALSE; + cm->con.udp.sock = g_socket_new(G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_UDP, + &error); + g_assert(error == NULL); + + GInetAddress *addr = g_inet_address_new_from_string("127.0.0.1"); + g_assert(addr); + GSocketAddress *saddr = g_inet_socket_address_new(addr, 64738); + + if (!g_socket_connect(cm->con.udp.sock, saddr, NULL, &error)) + return; + + cm->con.udp.connected = TRUE; + cm->con.udp.source = g_socket_create_source(cm->con.udp.sock, G_IO_IN, NULL); + g_source_set_callback(cm->con.udp.source, (GSourceFunc) read_udp, cm, NULL); + g_source_attach(cm->con.udp.source, NULL); + + do_udp_ping(cm); +} + static void connection_ready(GObject *source_object, GAsyncResult *res, gpointer user_data) { @@ -48,7 +204,6 @@ connection_ready(GObject *source_object, GAsyncResult *res, gpointer user_data) con->source = g_pollable_input_stream_create_source(con->input, NULL); g_source_set_callback(con->source, (GSourceFunc) read_cb, cm, NULL); g_source_attach(con->source, NULL); - g_source_unref(con->source); cmumble_protocol_init(cm); } diff --git a/src/connection.h b/src/connection.h index 508a71c..8a828f6 100644 --- a/src/connection.h +++ b/src/connection.h @@ -12,6 +12,12 @@ struct cmumble_connection { GOutputStream *output; GSource *source; + + struct { + GSocket *sock; + gboolean connected; + GSource *source; + } udp; }; struct cmumlbe; @@ -23,4 +29,7 @@ cmumble_connection_init(struct cmumlbe *cm, int cmumble_connection_fini(struct cmumlbe *cm); +void +cmumble_connection_udp_init(struct cmumlbe *cm); + #endif /* _CONNECTION_H_ */ diff --git a/src/crypt.c b/src/crypt.c new file mode 100644 index 0000000..f51ceb8 --- /dev/null +++ b/src/crypt.c @@ -0,0 +1,319 @@ +/* Copyright (C) 2009-2011, Martin Johansson + Copyright (C) 2005-2011, Thorvald Natvig + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the Developers nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * This code implements OCB-AES128. + * In the US, OCB is covered by patents. The inventor has given a license + * to all programs distributed under the GPL. + * uMurmur is BSD (revised) licensed, meaning you can use the code in a + * closed-source program. If you do, you'll have to either replace + * OCB with something else or get yourself a license. + */ + +#include +#include +#include "crypt.h" + +static void CryptState_ocb_encrypt(cryptState_t *cs, const unsigned char *plain, unsigned char *encrypted, unsigned int len, const unsigned char *nonce, unsigned char *tag); +static void CryptState_ocb_decrypt(cryptState_t *cs, const unsigned char *encrypted, unsigned char *plain, unsigned int len, const unsigned char *nonce, unsigned char *tag); + + +void CryptState_init(cryptState_t *cs) +{ + memset(cs->decrypt_history, 0, 0xff); + memset(cs->raw_key, 0, AES_BLOCK_SIZE); + memset(cs->encrypt_iv, 0, AES_BLOCK_SIZE); + memset(cs->decrypt_iv, 0, AES_BLOCK_SIZE); + cs->bInit = false; + cs->uiGood = cs->uiLate = cs->uiLost = cs->uiResync = 0; + cs->uiRemoteGood = cs->uiRemoteLate = cs->uiRemoteLost = cs->uiRemoteResync = 0; + /* + Timer_init(&cs->tLastGood); + Timer_init(&cs->tLastRequest); + */ +} + +void CryptState_setKey(cryptState_t *cs, const unsigned char *rkey, const unsigned char *eiv, const unsigned char *div) +{ + memcpy(cs->raw_key, rkey, AES_BLOCK_SIZE); + memcpy(cs->encrypt_iv, eiv, AES_BLOCK_SIZE); + memcpy(cs->decrypt_iv, div, AES_BLOCK_SIZE); + + AES_set_encrypt_key(cs->raw_key, 128, &cs->encrypt_key); + AES_set_decrypt_key(cs->raw_key, 128, &cs->decrypt_key); + + cs->bInit = true; +} + +void CryptState_setDecryptIV(cryptState_t *cs, const unsigned char *iv) +{ + memcpy(cs->decrypt_iv, iv, AES_BLOCK_SIZE); +} + +void CryptState_encrypt(cryptState_t *cs, const unsigned char *source, unsigned char *dst, unsigned int plain_length) +{ + unsigned char tag[AES_BLOCK_SIZE]; + int i; + // First, increase our IV. + for (i = 0; i < AES_BLOCK_SIZE; i++) + if (++cs->encrypt_iv[i]) + break; + + CryptState_ocb_encrypt(cs, source, dst+4, plain_length, cs->encrypt_iv, tag); + + dst[0] = cs->encrypt_iv[0]; + dst[1] = tag[0]; + dst[2] = tag[1]; + dst[3] = tag[2]; +} + +bool_t CryptState_decrypt(cryptState_t *cs, const unsigned char *source, unsigned char *dst, unsigned int crypted_length) +{ + if (crypted_length < 4) + return false; + + unsigned int plain_length = crypted_length - 4; + + unsigned char saveiv[AES_BLOCK_SIZE]; + unsigned char ivbyte = source[0]; + bool_t restore = false; + unsigned char tag[AES_BLOCK_SIZE]; + + int lost = 0; + int late = 0; + + memcpy(saveiv, cs->decrypt_iv, AES_BLOCK_SIZE); + + if (((cs->decrypt_iv[0] + 1) & 0xFF) == ivbyte) { + // In order as expected. + if (ivbyte > cs->decrypt_iv[0]) { + cs->decrypt_iv[0] = ivbyte; + } else if (ivbyte < cs->decrypt_iv[0]) { + int i; + cs->decrypt_iv[0] = ivbyte; + for (i = 1; i < AES_BLOCK_SIZE; i++) + if (++cs->decrypt_iv[i]) + break; + } else { + return false; + } + } else { + // This is either out of order or a repeat. + + int diff = ivbyte - cs->decrypt_iv[0]; + if (diff > 128) + diff = diff-256; + else if (diff < -128) + diff = diff+256; + + if ((ivbyte < cs->decrypt_iv[0]) && (diff > -30) && (diff < 0)) { + // Late packet, but no wraparound. + late = 1; + lost = -1; + cs->decrypt_iv[0] = ivbyte; + restore = true; + } else if ((ivbyte > cs->decrypt_iv[0]) && (diff > -30) && (diff < 0)) { + int i; + // Last was 0x02, here comes 0xff from last round + late = 1; + lost = -1; + cs->decrypt_iv[0] = ivbyte; + for (i = 1; i < AES_BLOCK_SIZE; i++) + if (cs->decrypt_iv[i]--) + break; + restore = true; + } else if ((ivbyte > cs->decrypt_iv[0]) && (diff > 0)) { + // Lost a few packets, but beyond that we're good. + lost = ivbyte - cs->decrypt_iv[0] - 1; + cs->decrypt_iv[0] = ivbyte; + } else if ((ivbyte < cs->decrypt_iv[0]) && (diff > 0)) { + int i; + // Lost a few packets, and wrapped around + lost = 256 - cs->decrypt_iv[0] + ivbyte - 1; + cs->decrypt_iv[0] = ivbyte; + for (i = 1; i < AES_BLOCK_SIZE; i++) + if (++cs->decrypt_iv[i]) + break; + } else { + return false; + } + + if (cs->decrypt_history[cs->decrypt_iv[0]] == cs->decrypt_iv[1]) { + memcpy(cs->decrypt_iv, saveiv, AES_BLOCK_SIZE); + return false; + } + } + + CryptState_ocb_decrypt(cs, source+4, dst, plain_length, cs->decrypt_iv, tag); + + if (memcmp(tag, source+1, 3) != 0) { + memcpy(cs->decrypt_iv, saveiv, AES_BLOCK_SIZE); + return false; + } + cs->decrypt_history[cs->decrypt_iv[0]] = cs->decrypt_iv[1]; + + if (restore) + memcpy(cs->decrypt_iv, saveiv, AES_BLOCK_SIZE); + + cs->uiGood++; + cs->uiLate += late; + cs->uiLost += lost; + + //Timer_restart(&cs->tLastGood); + return true; +} + +#if defined(__LP64__) +#define BLOCKSIZE 2 +#define SHIFTBITS 63 +typedef uint64_t subblock; + +#if __BYTE_ORDER == __BIG_ENDIAN +#define SWAPPED(x) (x) +#else +#ifdef __x86_64__ +#define SWAPPED(x) ({register uint64_t __out, __in = (x); __asm__("bswap %q0" : "=r"(__out) : "0"(__in)); __out;}) +#else +#include +#define SWAPPED(x) bswap_64(x) +#endif +#endif + +#else + +#define BLOCKSIZE 4 +#define SHIFTBITS 31 +typedef uint32_t subblock; +#define SWAPPED(x) htonl(x) + +#endif + +#define HIGHBIT (1<> SHIFTBITS; + int i; + for (i=0;i> SHIFTBITS)); + block[BLOCKSIZE-1] = SWAPPED((SWAPPED(block[BLOCKSIZE-1]) << 1) ^(carry * 0x87)); +} + +static void inline S3(subblock *block) { + subblock carry = SWAPPED(block[0]) >> SHIFTBITS; + int i; + for (i=0;i> SHIFTBITS)); + block[BLOCKSIZE-1] ^= SWAPPED((SWAPPED(block[BLOCKSIZE-1]) << 1) ^(carry * 0x87)); +} + +static void inline ZERO(subblock *block) { + int i; + for (i=0;iencrypt_key); +#define AESdecrypt(src, dst, cryptstate) AES_decrypt((unsigned char *)(src), (unsigned char *)(dst), &(cryptstate)->decrypt_key); + +void CryptState_ocb_encrypt(cryptState_t *cs, const unsigned char *plain, unsigned char *encrypted, unsigned int len, const unsigned char *nonce, unsigned char *tag) { + subblock checksum[BLOCKSIZE], delta[BLOCKSIZE], tmp[BLOCKSIZE], pad[BLOCKSIZE]; + + // Initialize + AESencrypt(nonce, delta, cs); + ZERO(checksum); + + while (len > AES_BLOCK_SIZE) { + S2(delta); + XOR(tmp, delta, (const subblock *)(plain)); + AESencrypt(tmp, tmp, cs); + XOR((subblock *)(encrypted), delta, tmp); + XOR(checksum, checksum, (subblock *)(plain)); + len -= AES_BLOCK_SIZE; + plain += AES_BLOCK_SIZE; + encrypted += AES_BLOCK_SIZE; + } + + S2(delta); + ZERO(tmp); + tmp[BLOCKSIZE - 1] = SWAPPED(len * 8); + XOR(tmp, tmp, delta); + AESencrypt(tmp, pad, cs); + memcpy(tmp, plain, len); + memcpy((unsigned char *)tmp + len, (unsigned char *)pad + len, AES_BLOCK_SIZE - len); + XOR(checksum, checksum, tmp); + XOR(tmp, pad, tmp); + memcpy(encrypted, tmp, len); + + S3(delta); + XOR(tmp, delta, checksum); + AESencrypt(tmp, tag, cs); +} + +void CryptState_ocb_decrypt(cryptState_t *cs, const unsigned char *encrypted, unsigned char *plain, unsigned int len, const unsigned char *nonce, unsigned char *tag) { + subblock checksum[BLOCKSIZE], delta[BLOCKSIZE], tmp[BLOCKSIZE], pad[BLOCKSIZE]; + // Initialize + AESencrypt(nonce, delta, cs); + ZERO(checksum); + + while (len > AES_BLOCK_SIZE) { + S2(delta); + XOR(tmp, delta, (const subblock *)(encrypted)); + AESdecrypt(tmp, tmp, cs); + XOR((subblock *)(plain), delta, tmp); + XOR(checksum, checksum, (const subblock *)(plain)); + len -= AES_BLOCK_SIZE; + plain += AES_BLOCK_SIZE; + encrypted += AES_BLOCK_SIZE; + } + + S2(delta); + ZERO(tmp); + tmp[BLOCKSIZE - 1] = SWAPPED(len * 8); + XOR(tmp, tmp, delta); + AESencrypt(tmp, pad, cs); + memset(tmp, 0, AES_BLOCK_SIZE); + memcpy(tmp, encrypted, len); + XOR(tmp, tmp, pad); + XOR(checksum, checksum, tmp); + memcpy(plain, tmp, len); + + S3(delta); + XOR(tmp, delta, checksum); + AESencrypt(tmp, tag, cs); +} diff --git a/src/crypt.h b/src/crypt.h new file mode 100644 index 0000000..30c0298 --- /dev/null +++ b/src/crypt.h @@ -0,0 +1,80 @@ +/* Copyright (C) 2009-2011, Martin Johansson + Copyright (C) 2005-2011, Thorvald Natvig + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the Developers nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef CRYPTSTATE_H_34564356 +#define CRYPTSTATE_H_34564356 + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include + +#include +#define bool_t gboolean +#define false FALSE +#define true TRUE + +typedef struct CryptState { + uint8_t raw_key[AES_BLOCK_SIZE]; + uint8_t encrypt_iv[AES_BLOCK_SIZE]; + uint8_t decrypt_iv[AES_BLOCK_SIZE]; + uint8_t decrypt_history[0x100]; + + unsigned int uiGood; + unsigned int uiLate; + unsigned int uiLost; + unsigned int uiResync; + + unsigned int uiRemoteGood; + unsigned int uiRemoteLate; + unsigned int uiRemoteLost; + unsigned int uiRemoteResync; + AES_KEY encrypt_key; + AES_KEY decrypt_key; + + //etimer_t tLastGood; + //etimer_t tLastRequest; + bool_t bInit; +} cryptState_t; + +void CryptState_init(cryptState_t *cs); +bool_t CryptState_isValid(cryptState_t *cs); +void CryptState_setKey(cryptState_t *cs, const unsigned char *rkey, const unsigned char *eiv, const unsigned char *div); +void CryptState_setDecryptIV(cryptState_t *cs, const unsigned char *iv); + +bool_t CryptState_decrypt(cryptState_t *cs, const unsigned char *source, unsigned char *dst, unsigned int crypted_length); +void CryptState_encrypt(cryptState_t *cs, const unsigned char *source, unsigned char *dst, unsigned int plain_length); + + +#endif -- cgit