Use ChiakiKeyState to 32bit fix key state overflow (Fix #172) (#359)

This commit is contained in:
Sven Scharmentke 2020-11-04 11:45:05 +01:00 committed by GitHub
parent 163fa81c03
commit 59e6603256
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 272 additions and 108 deletions

View file

@ -20,15 +20,20 @@ extern "C" {
#define CHIAKI_GKCRYPT_GMAC_KEY_REFRESH_KEY_POS 45000
#define CHIAKI_GKCRYPT_GMAC_KEY_REFRESH_IV_OFFSET 44910
typedef struct chiaki_key_state_t
{
uint64_t prev;
} ChiakiKeyState;
typedef struct chiaki_gkcrypt_t {
uint8_t index;
uint8_t *key_buf; // circular buffer of the ctr mode key stream
size_t key_buf_size;
size_t key_buf_populated; // size of key_buf that is already populated (on startup)
size_t key_buf_key_pos_min; // minimal key pos currently in key_buf
uint64_t key_buf_key_pos_min; // minimal key pos currently in key_buf
size_t key_buf_start_offset; // offset in key_buf of the minimal key pos
size_t last_key_pos; // last key pos that has been requested
uint64_t last_key_pos; // last key pos that has been requested
bool key_buf_thread_stop;
ChiakiMutex key_buf_mutex;
ChiakiCond key_buf_cond;
@ -50,14 +55,14 @@ struct chiaki_session_t;
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_init(ChiakiGKCrypt *gkcrypt, ChiakiLog *log, size_t key_buf_chunks, uint8_t index, const uint8_t *handshake_key, const uint8_t *ecdh_secret);
CHIAKI_EXPORT void chiaki_gkcrypt_fini(ChiakiGKCrypt *gkcrypt);
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gen_key_stream(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size);
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_get_key_stream(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size);
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_decrypt(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size);
static inline ChiakiErrorCode chiaki_gkcrypt_encrypt(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size) { return chiaki_gkcrypt_decrypt(gkcrypt, key_pos, buf, buf_size); }
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gen_key_stream(ChiakiGKCrypt *gkcrypt, uint64_t key_pos, uint8_t *buf, size_t buf_size);
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_get_key_stream(ChiakiGKCrypt *gkcrypt, uint64_t key_pos, uint8_t *buf, size_t buf_size);
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_decrypt(ChiakiGKCrypt *gkcrypt, uint64_t key_pos, uint8_t *buf, size_t buf_size);
static inline ChiakiErrorCode chiaki_gkcrypt_encrypt(ChiakiGKCrypt *gkcrypt, uint64_t key_pos, uint8_t *buf, size_t buf_size) { return chiaki_gkcrypt_decrypt(gkcrypt, key_pos, buf, buf_size); }
CHIAKI_EXPORT void chiaki_gkcrypt_gen_gmac_key(uint64_t index, const uint8_t *key_base, const uint8_t *iv, uint8_t *key_out);
CHIAKI_EXPORT void chiaki_gkcrypt_gen_new_gmac_key(ChiakiGKCrypt *gkcrypt, uint64_t index);
CHIAKI_EXPORT void chiaki_gkcrypt_gen_tmp_gmac_key(ChiakiGKCrypt *gkcrypt, uint64_t index, uint8_t *key_out);
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gmac(ChiakiGKCrypt *gkcrypt, size_t key_pos, const uint8_t *buf, size_t buf_size, uint8_t *gmac_out);
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gmac(ChiakiGKCrypt *gkcrypt, uint64_t key_pos, const uint8_t *buf, size_t buf_size, uint8_t *gmac_out);
static inline ChiakiGKCrypt *chiaki_gkcrypt_new(ChiakiLog *log, size_t key_buf_chunks, uint8_t index, const uint8_t *handshake_key, const uint8_t *ecdh_secret)
{
@ -81,12 +86,17 @@ static inline void chiaki_gkcrypt_free(ChiakiGKCrypt *gkcrypt)
free(gkcrypt);
}
typedef struct chiaki_key_state_t {
uint64_t prev;
} ChiakiKeyState;
CHIAKI_EXPORT void chiaki_key_state_init(ChiakiKeyState *state);
CHIAKI_EXPORT uint64_t chiaki_key_state_request_pos(ChiakiKeyState *state, uint32_t low);
/**
* @param commit whether to remember this key_pos to update the state. Should only be true after authentication to avoid DoS.
*/
CHIAKI_EXPORT uint64_t chiaki_key_state_request_pos(ChiakiKeyState *state, uint32_t low, bool commit);
/**
* Update the internal state after knowing that this key_pos is authentic.
*/
CHIAKI_EXPORT void chiaki_key_state_commit(ChiakiKeyState *state, uint64_t prev);
#ifdef __cplusplus
}

View file

@ -24,8 +24,6 @@
extern "C" {
#endif
typedef uint32_t ChiakiTakionPacketKeyPos;
typedef enum chiaki_takion_message_data_type_t {
CHIAKI_TAKION_MESSAGE_DATA_TYPE_PROTOBUF = 0,
CHIAKI_TAKION_MESSAGE_DATA_TYPE_9 = 9
@ -45,7 +43,7 @@ typedef struct chiaki_takion_av_packet_t
uint8_t adaptive_stream_index;
uint8_t byte_at_0x2c;
uint32_t key_pos;
uint64_t key_pos;
uint8_t *data; // not owned
size_t data_size;
@ -55,7 +53,7 @@ static inline uint8_t chiaki_takion_av_packet_audio_unit_size(ChiakiTakionAVPack
static inline uint8_t chiaki_takion_av_packet_audio_source_units_count(ChiakiTakionAVPacket *packet) { return packet->units_in_frame_fec & 0xf; }
static inline uint8_t chiaki_takion_av_packet_audio_fec_units_count(ChiakiTakionAVPacket *packet) { return (packet->units_in_frame_fec >> 4) & 0xf; }
typedef ChiakiErrorCode (*ChiakiTakionAVPacketParse)(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size);
typedef ChiakiErrorCode (*ChiakiTakionAVPacketParse)(ChiakiTakionAVPacket *packet, ChiakiKeyState *key_state, uint8_t *buf, size_t buf_size);
typedef struct chiaki_takion_congestion_packet_t
{
@ -133,7 +131,7 @@ typedef struct chiaki_takion_t
size_t postponed_packets_count;
ChiakiGKCrypt *gkcrypt_local; // if NULL (default), no gmac is calculated and nothing is encrypted
size_t key_pos_local;
uint64_t key_pos_local;
ChiakiMutex gkcrypt_local_mutex;
ChiakiGKCrypt *gkcrypt_remote; // if NULL (default), remote gmacs are IGNORED (!) and everything is expected to be unencrypted
@ -158,6 +156,8 @@ typedef struct chiaki_takion_t
uint32_t a_rwnd;
ChiakiTakionAVPacketParse av_packet_parse;
ChiakiKeyState key_state;
} ChiakiTakion;
@ -178,7 +178,7 @@ static inline void chiaki_takion_set_crypt(ChiakiTakion *takion, ChiakiGKCrypt *
* 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);
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_crypt_advance_key_pos(ChiakiTakion *takion, size_t data_size, uint64_t *key_pos);
/**
* Send a datagram directly on the socket.
@ -193,7 +193,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, const
*
* 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);
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t *buf, size_t buf_size, uint64_t key_pos);
/**
* Thread-safe while Takion is running.
@ -220,7 +220,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_history(ChiakiTakion *
#define CHIAKI_TAKION_V9_AV_HEADER_SIZE_VIDEO 0x17
#define CHIAKI_TAKION_V9_AV_HEADER_SIZE_AUDIO 0x12
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size);
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPacket *packet, ChiakiKeyState *key_state, uint8_t *buf, size_t buf_size);
#define CHIAKI_TAKION_V7_AV_HEADER_SIZE_BASE 0x12
#define CHIAKI_TAKION_V7_AV_HEADER_SIZE_VIDEO_ADD 0x3
@ -228,7 +228,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPac
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_format_header(uint8_t *buf, size_t buf_size, size_t *header_size_out, ChiakiTakionAVPacket *packet);
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size);
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_parse(ChiakiTakionAVPacket *packet, ChiakiKeyState *key_state, uint8_t *buf, size_t buf_size);
#ifdef __cplusplus
}

View file

@ -79,7 +79,6 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_init(ChiakiCtrl *ctrl, ChiakiSession *
goto error_notif_pipe;
return err;
error_notif_mutex:
chiaki_mutex_fini(&ctrl->notif_mutex);
error_notif_pipe:
chiaki_stop_pipe_fini(&ctrl->notif_pipe);

View file

@ -210,7 +210,7 @@ CHIAKI_EXPORT void chiaki_gkcrypt_gen_tmp_gmac_key(ChiakiGKCrypt *gkcrypt, uint6
memcpy(key_out, gkcrypt->key_gmac_base, sizeof(gkcrypt->key_gmac_base));
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gen_key_stream(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size)
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gen_key_stream(ChiakiGKCrypt *gkcrypt, uint64_t key_pos, uint8_t *buf, size_t buf_size)
{
assert(key_pos % CHIAKI_GKCRYPT_BLOCK_SIZE == 0);
assert(buf_size % CHIAKI_GKCRYPT_BLOCK_SIZE == 0);
@ -276,7 +276,7 @@ static bool gkcrypt_key_buf_should_generate(ChiakiGKCrypt *gkcrypt)
return gkcrypt->last_key_pos > gkcrypt->key_buf_key_pos_min + gkcrypt->key_buf_populated / 2;
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_get_key_stream(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size)
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_get_key_stream(ChiakiGKCrypt *gkcrypt, uint64_t key_pos, uint8_t *buf, size_t buf_size)
{
if(!gkcrypt->key_buf)
return chiaki_gkcrypt_gen_key_stream(gkcrypt, key_pos, buf, buf_size);
@ -291,7 +291,15 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_get_key_stream(ChiakiGKCrypt *gkcry
if(key_pos < gkcrypt->key_buf_key_pos_min
|| key_pos + buf_size >= gkcrypt->key_buf_key_pos_min + gkcrypt->key_buf_populated)
{
CHIAKI_LOGW(gkcrypt->log, "Requested key stream for key pos %#llx on GKCrypt %d, but it's not in the buffer", (int)key_pos, gkcrypt->index);
CHIAKI_LOGW(gkcrypt->log, "Requested key stream for key pos %#llx on GKCrypt %d, but it's not in the buffer:"
" key buf size %#llx, start offset: %#llx, populated: %#llx, min key pos: %#llx, last key pos: %#llx",
(unsigned long long)key_pos,
gkcrypt->index,
(unsigned long long)gkcrypt->key_buf_size,
(unsigned long long)gkcrypt->key_buf_start_offset,
(unsigned long long)gkcrypt->key_buf_populated,
(unsigned long long)gkcrypt->key_buf_key_pos_min,
(unsigned long long)gkcrypt->last_key_pos);
chiaki_mutex_unlock(&gkcrypt->key_buf_mutex);
err = chiaki_gkcrypt_gen_key_stream(gkcrypt, key_pos, buf, buf_size);
}
@ -318,9 +326,9 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_get_key_stream(ChiakiGKCrypt *gkcry
return err;
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_decrypt(ChiakiGKCrypt *gkcrypt, size_t key_pos, uint8_t *buf, size_t buf_size)
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_decrypt(ChiakiGKCrypt *gkcrypt, uint64_t key_pos, uint8_t *buf, size_t buf_size)
{
size_t padding_pre = key_pos % CHIAKI_GKCRYPT_BLOCK_SIZE;
uint64_t padding_pre = key_pos % CHIAKI_GKCRYPT_BLOCK_SIZE;
size_t full_size = ((padding_pre + buf_size + CHIAKI_GKCRYPT_BLOCK_SIZE - 1) / CHIAKI_GKCRYPT_BLOCK_SIZE) * CHIAKI_GKCRYPT_BLOCK_SIZE;
uint8_t *key_stream = malloc(full_size);
@ -340,7 +348,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_decrypt(ChiakiGKCrypt *gkcrypt, siz
return CHIAKI_ERR_SUCCESS;
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gmac(ChiakiGKCrypt *gkcrypt, size_t key_pos, const uint8_t *buf, size_t buf_size, uint8_t *gmac_out)
CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gmac(ChiakiGKCrypt *gkcrypt, uint64_t key_pos, const uint8_t *buf, size_t buf_size, uint8_t *gmac_out)
{
uint8_t iv[CHIAKI_GKCRYPT_BLOCK_SIZE];
counter_add(iv, gkcrypt->iv, key_pos / 0x10);
@ -463,7 +471,7 @@ static ChiakiErrorCode gkcrypt_generate_next_chunk(ChiakiGKCrypt *gkcrypt)
{
assert(gkcrypt->key_buf_populated + KEY_BUF_CHUNK_SIZE <= gkcrypt->key_buf_size);
size_t buf_offset = (gkcrypt->key_buf_start_offset + gkcrypt->key_buf_populated) % gkcrypt->key_buf_size;
size_t key_pos = gkcrypt->key_buf_key_pos_min + gkcrypt->key_buf_populated;
uint64_t key_pos = gkcrypt->key_buf_key_pos_min + gkcrypt->key_buf_populated;
uint8_t *buf_start = gkcrypt->key_buf + buf_offset;
chiaki_mutex_unlock(&gkcrypt->key_buf_mutex);
@ -505,7 +513,7 @@ static void *gkcrypt_thread_func(void *user)
if(gkcrypt->last_key_pos > gkcrypt->key_buf_key_pos_min + gkcrypt->key_buf_populated)
{
// skip ahead if the last key pos is already beyond our buffer
size_t key_pos = (gkcrypt->last_key_pos / KEY_BUF_CHUNK_SIZE) * KEY_BUF_CHUNK_SIZE;
uint64_t key_pos = (gkcrypt->last_key_pos / KEY_BUF_CHUNK_SIZE) * KEY_BUF_CHUNK_SIZE;
CHIAKI_LOGW(gkcrypt->log, "Already requested a higher key pos than in the buffer, skipping ahead from min %#llx to %#llx",
(unsigned long long)gkcrypt->key_buf_key_pos_min,
(unsigned long long)key_pos);
@ -533,7 +541,7 @@ CHIAKI_EXPORT void chiaki_key_state_init(ChiakiKeyState *state)
state->prev = 0;
}
CHIAKI_EXPORT uint64_t chiaki_key_state_request_pos(ChiakiKeyState *state, uint32_t low)
CHIAKI_EXPORT uint64_t chiaki_key_state_request_pos(ChiakiKeyState *state, uint32_t low, bool commit)
{
uint32_t prev_low = (uint32_t)state->prev;
uint32_t high = (uint32_t)(state->prev >> 32);
@ -541,5 +549,13 @@ CHIAKI_EXPORT uint64_t chiaki_key_state_request_pos(ChiakiKeyState *state, uint3
high++;
else if(chiaki_seq_num_32_lt(low, prev_low) && low > prev_low && high)
high--;
return state->prev = (((uint64_t)high) << 32) | ((uint64_t)low);
uint64_t res = (((uint64_t)high) << 32) | ((uint64_t)low);
if(commit)
state->prev = res;
return res;
}
CHIAKI_EXPORT void chiaki_key_state_commit(ChiakiKeyState *state, uint64_t prev)
{
state->prev = prev;
}

View file

@ -16,6 +16,7 @@
#include <pb_decode.h>
#include <pb.h>
#include <chiaki/takion.h>
#include <chiaki/gkcrypt.h>
#ifndef _WIN32
#include <sys/types.h>
@ -85,6 +86,8 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_init(ChiakiSenkusha *senkusha, Chi
senkusha->ping_tag = 0;
senkusha->pong_time_us = 0;
chiaki_key_state_init(&senkusha->takion.key_state);
return CHIAKI_ERR_SUCCESS;
error_state_mutex:

View file

@ -3,6 +3,7 @@
#include <chiaki/takion.h>
#include <chiaki/congestioncontrol.h>
#include <chiaki/random.h>
#include <chiaki/gkcrypt.h>
#include <fcntl.h>
#include <stdbool.h>
@ -71,6 +72,8 @@ int takion_packet_type_mac_offset(TakionPacketType type)
case TAKION_PACKET_TYPE_VIDEO:
case TAKION_PACKET_TYPE_AUDIO:
return 0xa;
case TAKION_PACKET_TYPE_CONGESTION:
return 7;
default:
return -1;
}
@ -88,6 +91,8 @@ int takion_packet_type_key_pos_offset(TakionPacketType type)
case TAKION_PACKET_TYPE_VIDEO:
case TAKION_PACKET_TYPE_AUDIO:
return 0xe;
case TAKION_PACKET_TYPE_CONGESTION:
return 0xb;
default:
return -1;
}
@ -107,7 +112,7 @@ typedef struct takion_message_t
{
uint32_t tag;
//uint8_t zero[4];
uint32_t key_pos;
uint64_t key_pos;
uint8_t chunk_type;
uint8_t chunk_flags;
@ -162,7 +167,7 @@ static void takion_handle_packet_message(ChiakiTakion *takion, uint8_t *buf, siz
static void takion_handle_packet_message_data(ChiakiTakion *takion, uint8_t *packet_buf, size_t packet_buf_size, uint8_t type_b, uint8_t *payload, size_t payload_size);
static void takion_handle_packet_message_data_ack(ChiakiTakion *takion, uint8_t flags, uint8_t *buf, size_t buf_size);
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, uint32_t key_pos, uint8_t chunk_type, uint8_t chunk_flags, size_t payload_data_size);
static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint64_t key_pos, uint8_t chunk_type, uint8_t chunk_flags, size_t payload_data_size);
static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMessagePayloadInit *payload);
static ChiakiErrorCode takion_send_message_cookie(ChiakiTakion *takion, uint8_t *cookie);
static ChiakiErrorCode takion_recv(ChiakiTakion *takion, uint8_t *buf, size_t *buf_size, uint64_t timeout_ms);
@ -304,7 +309,7 @@ CHIAKI_EXPORT void chiaki_takion_close(ChiakiTakion *takion)
chiaki_mutex_fini(&takion->gkcrypt_local_mutex);
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_crypt_advance_key_pos(ChiakiTakion *takion, size_t data_size, size_t *key_pos)
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_crypt_advance_key_pos(ChiakiTakion *takion, size_t data_size, uint64_t *key_pos)
{
ChiakiErrorCode err = chiaki_mutex_lock(&takion->gkcrypt_local_mutex);
if(err != CHIAKI_ERR_SUCCESS)
@ -312,7 +317,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_crypt_advance_key_pos(ChiakiTakion *
if(takion->gkcrypt_local)
{
size_t cur = takion->key_pos_local;
uint64_t cur = takion->key_pos_local;
if(SIZE_MAX - cur < data_size)
{
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
@ -337,8 +342,26 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, const
return CHIAKI_ERR_SUCCESS;
}
static ChiakiErrorCode chiaki_takion_packet_read_key_pos(ChiakiTakion *takion, uint8_t *buf, size_t buf_size, uint64_t *key_pos_out)
{
if(buf_size < 1)
return CHIAKI_ERR_BUF_TOO_SMALL;
static ChiakiErrorCode chiaki_takion_packet_mac(ChiakiGKCrypt *crypt, uint8_t *buf, size_t buf_size, uint8_t *mac_out, uint8_t *mac_old_out, ChiakiTakionPacketKeyPos *key_pos_out)
TakionPacketType base_type = buf[0] & TAKION_PACKET_BASE_TYPE_MASK;
int key_pos_offset = takion_packet_type_key_pos_offset(base_type);
if(key_pos_offset < 0)
return CHIAKI_ERR_INVALID_DATA;
if(buf_size < key_pos_offset + sizeof(uint32_t))
return CHIAKI_ERR_BUF_TOO_SMALL;
uint32_t key_pos_low = ntohl(*((chiaki_unaligned_uint32_t *)(buf + key_pos_offset)));
*key_pos_out = chiaki_key_state_request_pos(&takion->key_state, key_pos_low, false);
return CHIAKI_ERR_SUCCESS;
}
static ChiakiErrorCode chiaki_takion_packet_mac(ChiakiGKCrypt *crypt, uint8_t *buf, size_t buf_size, uint64_t key_pos, uint8_t *mac_out, uint8_t *mac_old_out)
{
if(buf_size < 1)
return CHIAKI_ERR_BUF_TOO_SMALL;
@ -349,7 +372,7 @@ static ChiakiErrorCode chiaki_takion_packet_mac(ChiakiGKCrypt *crypt, uint8_t *b
if(mac_offset < 0 || key_pos_offset < 0)
return CHIAKI_ERR_INVALID_DATA;
if(buf_size < mac_offset + CHIAKI_GKCRYPT_GMAC_SIZE || buf_size < key_pos_offset + sizeof(ChiakiTakionPacketKeyPos))
if(buf_size < mac_offset + CHIAKI_GKCRYPT_GMAC_SIZE || buf_size < key_pos_offset + sizeof(uint32_t))
return CHIAKI_ERR_BUF_TOO_SMALL;
if(mac_old_out)
@ -357,31 +380,31 @@ static ChiakiErrorCode chiaki_takion_packet_mac(ChiakiGKCrypt *crypt, uint8_t *b
memset(buf + mac_offset, 0, CHIAKI_GKCRYPT_GMAC_SIZE);
ChiakiTakionPacketKeyPos key_pos = ntohl(*((ChiakiTakionPacketKeyPos *)(buf + key_pos_offset)));
if(crypt)
{
uint8_t key_pos_tmp[sizeof(uint32_t)];
if(base_type == TAKION_PACKET_TYPE_CONTROL)
memset(buf + key_pos_offset, 0, sizeof(ChiakiTakionPacketKeyPos));
{
memcpy(key_pos_tmp, buf + key_pos_offset, sizeof(uint32_t));
memset(buf + key_pos_offset, 0, sizeof(uint32_t));
}
chiaki_gkcrypt_gmac(crypt, key_pos, buf, buf_size, buf + mac_offset);
*((ChiakiTakionPacketKeyPos *)(buf + key_pos_offset)) = htonl(key_pos);
if(base_type == TAKION_PACKET_TYPE_CONTROL)
memcpy(buf + key_pos_offset, key_pos_tmp, sizeof(uint32_t));
}
if(key_pos_out)
*key_pos_out = key_pos;
memcpy(mac_out, buf + mac_offset, CHIAKI_GKCRYPT_GMAC_SIZE);
return CHIAKI_ERR_SUCCESS;
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t *buf, size_t buf_size)
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t *buf, size_t buf_size, uint64_t key_pos)
{
ChiakiErrorCode err = chiaki_mutex_lock(&takion->gkcrypt_local_mutex);
if(err != CHIAKI_ERR_SUCCESS)
return err;
uint8_t mac[CHIAKI_GKCRYPT_GMAC_SIZE];
err = chiaki_takion_packet_mac(takion->gkcrypt_local, buf, buf_size, mac, NULL, NULL);
err = chiaki_takion_packet_mac(takion->gkcrypt_local, buf, buf_size, key_pos, mac, NULL);
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
if(err != CHIAKI_ERR_SUCCESS)
return err;
@ -397,7 +420,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *taki
// TODO: can we make this more memory-efficient?
// TODO: split packet if necessary?
size_t key_pos;
uint64_t key_pos;
ChiakiErrorCode err = chiaki_takion_crypt_advance_key_pos(takion, buf_size, &key_pos);
if(err != CHIAKI_ERR_SUCCESS)
return err;
@ -424,7 +447,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *taki
*(msg_payload + 8) = 0;
memcpy(msg_payload + 9, buf, buf_size);
err = chiaki_takion_send(takion, packet_buf, packet_size); // will alter packet_buf with gmac
err = chiaki_takion_send(takion, packet_buf, packet_size, key_pos); // will alter packet_buf with gmac
if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(takion->log, "Takion failed to send data packet: %s", chiaki_error_string(err));
@ -445,7 +468,7 @@ static ChiakiErrorCode chiaki_takion_send_message_data_ack(ChiakiTakion *takion,
uint8_t buf[1 + TAKION_MESSAGE_HEADER_SIZE + 0xc];
buf[0] = TAKION_PACKET_TYPE_CONTROL;
size_t key_pos;
uint64_t key_pos;
ChiakiErrorCode err = chiaki_takion_crypt_advance_key_pos(takion, sizeof(buf), &key_pos);
if(err != CHIAKI_ERR_SUCCESS)
return err;
@ -458,7 +481,7 @@ static ChiakiErrorCode chiaki_takion_send_message_data_ack(ChiakiTakion *takion,
*((chiaki_unaligned_uint16_t *)(data_ack + 8)) = 0;
*((chiaki_unaligned_uint16_t *)(data_ack + 0xa)) = 0;
return chiaki_takion_send(takion, buf, sizeof(buf));
return chiaki_takion_send(takion, buf, sizeof(buf), key_pos);
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet)
@ -470,19 +493,15 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion
*((chiaki_unaligned_uint16_t *)(buf + 3)) = htons(packet->word_1);
*((chiaki_unaligned_uint16_t *)(buf + 5)) = htons(packet->word_2);
ChiakiErrorCode err = chiaki_mutex_lock(&takion->gkcrypt_local_mutex);
if(err != CHIAKI_ERR_SUCCESS)
return err;
*((chiaki_unaligned_uint32_t *)(buf + 0xb)) = htonl((uint32_t)takion->key_pos_local); // TODO: is this correct? shouldn't key_pos be 0 for mac calculation?
err = chiaki_gkcrypt_gmac(takion->gkcrypt_local, takion->key_pos_local, buf, sizeof(buf), buf + 7);
takion->key_pos_local += sizeof(buf);
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
uint64_t key_pos;
ChiakiErrorCode err = chiaki_takion_crypt_advance_key_pos(takion, sizeof(buf), &key_pos);
if(err != CHIAKI_ERR_SUCCESS)
return err;
*((chiaki_unaligned_uint32_t *)(buf + 0xb)) = htonl((uint32_t)key_pos); // TODO: is this correct? shouldn't key_pos be 0 for mac calculation?
//chiaki_log_hexdump(takion->log, CHIAKI_LOG_DEBUG, buf, sizeof(buf));
return chiaki_takion_send_raw(takion, buf, sizeof(buf));
return chiaki_takion_send(takion, buf, sizeof(buf), key_pos);
}
static ChiakiErrorCode takion_send_feedback_packet(ChiakiTakion *takion, uint8_t *buf, size_t buf_size)
@ -495,7 +514,7 @@ static ChiakiErrorCode takion_send_feedback_packet(ChiakiTakion *takion, uint8_t
if(err != CHIAKI_ERR_SUCCESS)
return err;
size_t key_pos;
uint64_t key_pos;
err = chiaki_takion_crypt_advance_key_pos(takion, payload_size + CHIAKI_GKCRYPT_BLOCK_SIZE, &key_pos);
if(err != CHIAKI_ERR_SUCCESS)
goto beach;
@ -780,8 +799,14 @@ static ChiakiErrorCode takion_handle_packet_mac(ChiakiTakion *takion, uint8_t ba
uint8_t mac[CHIAKI_GKCRYPT_GMAC_SIZE];
uint8_t mac_expected[CHIAKI_GKCRYPT_GMAC_SIZE];
ChiakiTakionPacketKeyPos key_pos;
ChiakiErrorCode err = chiaki_takion_packet_mac(takion->gkcrypt_remote, buf, buf_size, mac_expected, mac, &key_pos);
uint64_t key_pos;
ChiakiErrorCode err = chiaki_takion_packet_read_key_pos(takion, buf, buf_size, &key_pos);
if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(takion->log, "Takion failed to pull key_pos out of received packet");
return err;
}
err = chiaki_takion_packet_mac(takion->gkcrypt_remote, buf, buf_size, key_pos, mac_expected, mac);
if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(takion->log, "Takion failed to calculate mac for received packet");
@ -799,6 +824,8 @@ static ChiakiErrorCode takion_handle_packet_mac(ChiakiTakion *takion, uint8_t ba
return CHIAKI_ERR_INVALID_MAC;
}
chiaki_key_state_commit(&takion->key_state, key_pos);
return CHIAKI_ERR_SUCCESS;
}
@ -1014,7 +1041,7 @@ 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
*/
static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint32_t key_pos, uint8_t chunk_type, uint8_t chunk_flags, size_t payload_data_size)
static void takion_write_message_header(uint8_t *buf, uint32_t tag, uint64_t key_pos, uint8_t chunk_type, uint8_t chunk_flags, size_t payload_data_size)
{
*((chiaki_unaligned_uint32_t *)(buf + 0)) = htonl(tag);
memset(buf + 4, 0, CHIAKI_GKCRYPT_GMAC_SIZE);
@ -1033,7 +1060,8 @@ static ChiakiErrorCode takion_parse_message(ChiakiTakion *takion, uint8_t *buf,
}
msg->tag = ntohl(*((chiaki_unaligned_uint32_t *)buf));
msg->key_pos = ntohl(*((chiaki_unaligned_uint32_t *)(buf + 0x8)));
uint32_t key_pos_low = ntohl(*((chiaki_unaligned_uint32_t *)(buf + 0x8)));
msg->key_pos = chiaki_key_state_request_pos(&takion->key_state, key_pos_low, true);
msg->chunk_type = buf[0xc];
msg->chunk_flags = buf[0xd];
msg->payload_size = ntohs(*((chiaki_unaligned_uint16_t *)(buf + 0xe)));
@ -1185,7 +1213,7 @@ static void takion_handle_packet_av(ChiakiTakion *takion, uint8_t base_type, uin
assert(base_type == TAKION_PACKET_TYPE_VIDEO || base_type == TAKION_PACKET_TYPE_AUDIO);
ChiakiTakionAVPacket packet;
ChiakiErrorCode err = takion->av_packet_parse(&packet, buf, buf_size);
ChiakiErrorCode err = takion->av_packet_parse(&packet, &takion->key_state, buf, buf_size);
if(err != CHIAKI_ERR_SUCCESS)
{
if(err == CHIAKI_ERR_BUF_TOO_SMALL)
@ -1202,7 +1230,7 @@ static void takion_handle_packet_av(ChiakiTakion *takion, uint8_t base_type, uin
}
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size)
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPacket *packet, ChiakiKeyState *key_state, uint8_t *buf, size_t buf_size)
{
memset(packet, 0, sizeof(ChiakiTakionAVPacket));
@ -1242,8 +1270,8 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v9_av_packet_parse(ChiakiTakionAVPac
}
packet->codec = av[8];
packet->key_pos = ntohl(*((chiaki_unaligned_uint32_t *)(av + 0xd)));
uint32_t key_pos_low = ntohl(*((chiaki_unaligned_uint32_t *)(av + 0xd)));
packet->key_pos = chiaki_key_state_request_pos(key_state, key_pos_low, true);
uint8_t unknown_1 = av[0x11];
@ -1313,7 +1341,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_format_header(uint8_t *
*(chiaki_unaligned_uint32_t *)(buf + 0xa) = 0; // unknown
*(chiaki_unaligned_uint32_t *)(buf + 0xe) = packet->key_pos;
*(chiaki_unaligned_uint32_t *)(buf + 0xe) = (uint32_t)packet->key_pos;
uint8_t *cur = buf + 0x12;
if(packet->is_video)
@ -1332,7 +1360,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_format_header(uint8_t *
return CHIAKI_ERR_SUCCESS;
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t *buf, size_t buf_size)
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_parse(ChiakiTakionAVPacket *packet, ChiakiKeyState *key_state, uint8_t *buf, size_t buf_size)
{
memset(packet, 0, sizeof(ChiakiTakionAVPacket));

View file

@ -58,6 +58,7 @@ static MunitResult test_key_stream(const MunitParameter params[], void *user)
static const uint8_t gkcrypt_key[] = { 0x8, 0x81, 0x6f, 0xa2, 0xe5, 0x55, 0x89, 0x61, 0xd5, 0xa2, 0x86, 0xd9, 0xe, 0xec, 0x5b, 0x8c };
static const uint8_t gkcrypt_iv[] = { 0x2a, 0xe1, 0xbb, 0x3d, 0x84, 0xdc, 0x9a, 0xa9, 0xc3, 0x52, 0xa4, 0xcf, 0x3f, 0xfb, 0x8b, 0x72 };
static const uint8_t key_stream[] = { 0xf, 0x6d, 0x89, 0x85, 0x5b, 0xa7, 0x86, 0x74, 0x5b, 0xa1, 0xfe, 0x5c, 0x81, 0x19, 0x6c, 0xd5, 0x54, 0xc4, 0x1c, 0xca, 0xf6, 0xe9, 0x34, 0xa4, 0x89, 0x26, 0x98, 0xb0, 0x62, 0x12, 0xb3, 0x1a };
static const uint8_t key_stream_high[] = { 0x14, 0x31, 0x9f, 0xf8, 0xbe, 0x08, 0x17, 0xa4, 0xfc, 0x28, 0x49, 0x0b, 0x1e, 0x5f, 0x7b, 0x7e, 0xfa, 0xe9, 0x14, 0xde, 0xc6, 0xdf, 0xe7, 0x5d, 0xd6, 0x9c, 0x75, 0x3f, 0x94, 0x62, 0xd5, 0x2c };
ChiakiLog log;
@ -79,6 +80,17 @@ static MunitResult test_key_stream(const MunitParameter params[], void *user)
munit_assert_memory_equal(sizeof(key_stream), key_stream_result, key_stream);
uint64_t key_pos = ((uint64_t)(1ull << 32)) + 0x420;
err = chiaki_gkcrypt_gen_key_stream(&gkcrypt, key_pos, key_stream_result, sizeof(key_stream_result));
if (err != CHIAKI_ERR_SUCCESS)
{
chiaki_gkcrypt_fini(&gkcrypt);
return MUNIT_ERROR;
}
munit_assert_memory_equal(sizeof(key_stream_high), key_stream_result, key_stream_high);
chiaki_gkcrypt_fini(&gkcrypt);
return MUNIT_OK;
}
@ -92,6 +104,7 @@ static MunitResult test_endecrypt(const MunitParameter params[], void *user)
static const uint8_t gkcrypt_iv[] = { 0xef, 0x20, 0x40, 0xc2, 0x15, 0x3c, 0x2, 0x66, 0x32, 0x1f, 0x42, 0xbb, 0xf4, 0x50, 0x34, 0x4d };
static const uint8_t clear_data[] = { 0x4e, 0x61, 0x9f, 0x94, 0x5d, 0x4b, 0x8e, 0xbd, 0x2a, 0x15, 0x4d, 0x3, 0x6a, 0xcd, 0x49, 0x56, 0x9c, 0xc7, 0x5c, 0xe3, 0xe7, 0x0, 0x17, 0x9a, 0x38, 0xd9, 0x69, 0x53, 0x45, 0xf9, 0xc, 0xb5, 0x8c, 0x5, 0x65, 0xf, 0x70 };
static const uint8_t enc_data[] = { 0x23, 0xf4, 0x8d, 0xd8, 0xaa, 0xf9, 0x58, 0x9b, 0xb1, 0x94, 0x4f, 0xad, 0x2b, 0x8d, 0xaa, 0x8d, 0x25, 0x88, 0xfa, 0xf8, 0xb6, 0xd4, 0x17, 0xf4, 0x5f, 0x78, 0xec, 0xf5, 0x4e, 0x37, 0x20, 0xb0, 0x76, 0x81, 0x7, 0x67, 0x9a };
static const uint8_t enc_data_high[] = { 0x2b, 0x9e, 0xe9, 0x83, 0x27, 0x44, 0x08, 0xb1, 0x17, 0xf5, 0x37, 0xa0, 0xd9, 0xc2, 0xc6, 0x05, 0x95, 0x78, 0xb2, 0x78, 0xfd, 0x17, 0x8c, 0x52, 0xf4, 0x17, 0x9d, 0xee, 0x3f, 0x62, 0xe6, 0x30, 0x01, 0x61, 0x4c, 0xf4, 0xa1 };
ChiakiLog log;
@ -113,6 +126,7 @@ static MunitResult test_endecrypt(const MunitParameter params[], void *user)
uint8_t buf[0x25];
// Low
memcpy(buf, clear_data, sizeof(buf));
err = chiaki_gkcrypt_encrypt(&gkcrypt, 0x11, buf, sizeof(buf));
if(err != CHIAKI_ERR_SUCCESS)
@ -131,6 +145,26 @@ static MunitResult test_endecrypt(const MunitParameter params[], void *user)
}
munit_assert_memory_equal(sizeof(buf), buf, enc_data);
// High
uint64_t key_pos_high = ((uint64_t)(1ull << 32)) + 0x420;
memcpy(buf, clear_data, sizeof(buf));
err = chiaki_gkcrypt_encrypt(&gkcrypt, key_pos_high, buf, sizeof(buf));
if (err != CHIAKI_ERR_SUCCESS)
{
chiaki_gkcrypt_fini(&gkcrypt);
return MUNIT_ERROR;
}
munit_assert_memory_equal(sizeof(buf), buf, enc_data_high);
memcpy(buf, clear_data, sizeof(buf));
err = chiaki_gkcrypt_decrypt(&gkcrypt, key_pos_high, buf, sizeof(buf));
if (err != CHIAKI_ERR_SUCCESS)
{
chiaki_gkcrypt_fini(&gkcrypt);
return MUNIT_ERROR;
}
munit_assert_memory_equal(sizeof(buf), buf, enc_data_high);
chiaki_gkcrypt_fini(&gkcrypt);
return MUNIT_OK;
}
@ -158,15 +192,19 @@ static MunitResult test_gmac(const MunitParameter params[], void *user)
0x64, 0x2d, 0xcb, 0x98, 0x0f, 0x43, 0xa6, 0xe1, 0x4c, 0xe7, 0x9f, 0x2d, 0xab, 0x94, 0x01, 0xd7,
0x52, 0x84, 0x19 };
static const size_t key_pos = 0x69a0;
static const uint64_t key_pos = 0x69a0;
static const uint64_t key_pos_high = ((uint64_t)(1ull << 32)) + 0x420;
static const uint8_t gmac_expected[] = { 0x6f, 0x81, 0x10, 0x97 };
static const uint8_t gmac_expected_high[] = { 0x4a, 0x30, 0x98, 0x10 };
ChiakiGKCrypt gkcrypt;
memset(&gkcrypt, 0, sizeof(gkcrypt));
// Low
memset(&gkcrypt, 0, sizeof(gkcrypt));
memcpy(gkcrypt.key_gmac_current, gkcrypt_key, sizeof(gkcrypt.key_gmac_current));
memcpy(gkcrypt.iv, gkcrypt_iv, sizeof(gkcrypt.iv));
gkcrypt.key_buf = NULL;
gkcrypt.key_buf_size = 0;
gkcrypt.key_gmac_index_current = 0;
@ -178,6 +216,21 @@ static MunitResult test_gmac(const MunitParameter params[], void *user)
munit_assert_memory_equal(sizeof(gmac), gmac, gmac_expected);
// High
memset(&gkcrypt, 0, sizeof(gkcrypt));
memcpy(gkcrypt.key_gmac_current, gkcrypt_key, sizeof(gkcrypt.key_gmac_current));
memcpy(gkcrypt.iv, gkcrypt_iv, sizeof(gkcrypt.iv));
gkcrypt.key_buf = NULL;
gkcrypt.key_buf_size = 0;
gkcrypt.key_gmac_index_current = 0;
err = chiaki_gkcrypt_gmac(&gkcrypt, key_pos_high, buf, sizeof(buf), gmac);
if (err != CHIAKI_ERR_SUCCESS)
return MUNIT_ERROR;
munit_assert_memory_equal(sizeof(gmac), gmac, gmac_expected_high);
return MUNIT_OK;
}
@ -242,9 +295,11 @@ static MunitResult test_gmac_split(const MunitParameter params[], void *user)
0xfa, 0x44, 0xc6, 0xd8, 0x19, 0x1, 0x8d, 0x41, 0x1f, 0xc7, 0xf, 0x89, 0x1d, 0xef, 0x34, 0x9a,
0x68, 0x77, 0x8c };
static const size_t key_pos = 0xadf0;
static const uint64_t key_pos = 0xadf0;
static const uint64_t key_pos_high = ((uint64_t)(1ull << 32)) + 0x420;
static const uint8_t gmac_expected[] = { 0xd6, 0x6a, 0x07, 0xb7 };
static const uint8_t gmac_expected_high[] = { 0xf0, 0x17, 0x95, 0x3c };
ChiakiGKCrypt gkcrypt;
memset(&gkcrypt, 0, sizeof(gkcrypt));
@ -262,6 +317,21 @@ static MunitResult test_gmac_split(const MunitParameter params[], void *user)
munit_assert_memory_equal(sizeof(gmac), gmac, gmac_expected);
// High
memset(&gkcrypt, 0, sizeof(gkcrypt));
memcpy(gkcrypt.key_gmac_current, gkcrypt_key, sizeof(gkcrypt.key_gmac_current));
memcpy(gkcrypt.iv, gkcrypt_iv, sizeof(gkcrypt.iv));
gkcrypt.key_buf = NULL;
gkcrypt.key_buf_size = 0;
gkcrypt.key_gmac_index_current = 0;
err = chiaki_gkcrypt_gmac(&gkcrypt, key_pos_high, buf, sizeof(buf), gmac);
if (err != CHIAKI_ERR_SUCCESS)
return MUNIT_ERROR;
munit_assert_memory_equal(sizeof(gmac), gmac, gmac_expected_high);
return MUNIT_OK;
}
@ -290,7 +360,7 @@ static MunitResult test_gmac_multiple_of_key_refresh(const MunitParameter params
0xbe, 0xfd, 0xee };
static const uint8_t crypt_index = 3;
static const size_t key_pos = 0x6b1de0; // % CHIAKI_GKCRYPT_GMAC_KEY_REFRESH_KEY_POS == 0
static const uint64_t key_pos = 0x6b1de0; // % CHIAKI_GKCRYPT_GMAC_KEY_REFRESH_KEY_POS == 0
static const uint8_t gmac_expected[] = { 0x20, 0xcc, 0xa5, 0xf1 };
ChiakiLog log;

View file

@ -9,26 +9,51 @@ static MunitResult test_key_state(const MunitParameter params[], void *user)
ChiakiKeyState state;
chiaki_key_state_init(&state);
uint64_t pos = chiaki_key_state_request_pos(&state, 0);
uint64_t pos = chiaki_key_state_request_pos(&state, 0, true);
munit_assert_uint64(pos, ==, 0);
pos = chiaki_key_state_request_pos(&state, 0x1337);
pos = chiaki_key_state_request_pos(&state, 0x1337, true);
munit_assert_uint64(pos, ==, 0x1337);
pos = chiaki_key_state_request_pos(&state, 0xffff0000);
pos = chiaki_key_state_request_pos(&state, 0xffff0000, true);
munit_assert_uint64(pos, ==, 0xffff0000);
pos = chiaki_key_state_request_pos(&state, 0x1337);
pos = chiaki_key_state_request_pos(&state, 0x1337, true);
munit_assert_uint64(pos, ==, 0x100001337);
pos = chiaki_key_state_request_pos(&state, 0xffff1337);
pos = chiaki_key_state_request_pos(&state, 0xffff1337, true);
munit_assert_uint64(pos, ==, 0xffff1337);
pos = chiaki_key_state_request_pos(&state, 0x50000000);
pos = chiaki_key_state_request_pos(&state, 0x50000000, true);
munit_assert_uint64(pos, ==, 0x150000000);
pos = chiaki_key_state_request_pos(&state, 0xb0000000);
pos = chiaki_key_state_request_pos(&state, 0xb0000000, true);
munit_assert_uint64(pos, ==, 0x1b0000000);
pos = chiaki_key_state_request_pos(&state, 0x00000000);
pos = chiaki_key_state_request_pos(&state, 0x00000000, true);
munit_assert_uint64(pos, ==, 0x200000000);
return MUNIT_OK;
}
static MunitResult test_key_state_nocommit(const MunitParameter params[], void *user)
{
ChiakiKeyState state;
chiaki_key_state_init(&state);
uint64_t pos = chiaki_key_state_request_pos(&state, 0, false);
munit_assert_uint64(pos, ==, 0);
pos = chiaki_key_state_request_pos(&state, 0x1337, false);
munit_assert_uint64(pos, ==, 0x1337);
pos = chiaki_key_state_request_pos(&state, 0xffff0000, false);
munit_assert_uint64(pos, ==, 0xffff0000);
pos = chiaki_key_state_request_pos(&state, 0x1337, false);
munit_assert_uint64(pos, ==, 0x1337);
pos = chiaki_key_state_request_pos(&state, 0xffff1337, false);
munit_assert_uint64(pos, ==, 0xffff1337);
pos = chiaki_key_state_request_pos(&state, 0x50000000, false);
munit_assert_uint64(pos, ==, 0x50000000);
pos = chiaki_key_state_request_pos(&state, 0xb0000000, false);
munit_assert_uint64(pos, ==, 0xb0000000);
pos = chiaki_key_state_request_pos(&state, 0x00000000, false);
munit_assert_uint64(pos, ==, 0);
return MUNIT_OK;
}
MunitTest tests_key_state[] = {
{
"/key_state",
@ -38,5 +63,13 @@ MunitTest tests_key_state[] = {
MUNIT_TEST_OPTION_NONE,
NULL
},
{
"/key_state_nocommit",
test_key_state_nocommit,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};

View file

@ -28,9 +28,12 @@ static MunitResult test_av_packet_parse(const MunitParameter params[], void *use
0x57, 0x5a, 0x76, 0x0, 0xc5, 0xe0, 0x93, 0xa9, 0xf5, 0x32, 0x5d, 0xee, 0xf7, 0x9d
};
ChiakiKeyState key_state;
chiaki_key_state_init(&key_state);
ChiakiTakionAVPacket av_packet;
ChiakiErrorCode err = chiaki_takion_v9_av_packet_parse(&av_packet, packet, sizeof(packet));
ChiakiErrorCode err = chiaki_takion_v9_av_packet_parse(&av_packet, &key_state, packet, sizeof(packet));
munit_assert_int(err, ==, CHIAKI_ERR_SUCCESS);
munit_assert(av_packet.is_video);

View file

@ -9,7 +9,9 @@ if(err != CHIAKI_ERR_SUCCESS)
return MUNIT_ERROR;
// -- frame --
// -- frame -- ChiakiKeyState key_state;
ChiakiKeyState key_state;
chiaki_key_state_init(&key_state);
uint8_t packet_0[126]; size_t packet_0_size = sizeof(packet_0); if(chiaki_base64_decode("AgAAAAEAAAQBAwlCI7oAAACAA5gAhJT79yG83L9WhXCDP/h48VDjBL03cGscKH6DLQ3ZOzh007JcllEEIpTP3DbJwYAF5MGH2BwWJJTcbZATOGrzCznFMInIL7pWssSgxQBcf2q+u+vECFWQ5zvEQsq4RxQs3bre0DchyEMz", 168, packet_0, &packet_0_size) != CHIAKI_ERR_SUCCESS || packet_0_size != 126) return MUNIT_ERROR;
uint8_t nalu_0[105]; size_t nalu_0_size = sizeof(nalu_0); if(chiaki_base64_decode("AAMAAAABZYiAhn8AL8gD/wh+/miASsv/rw5fm2PYQAAAAwAAAwAFIc42jXIHLchAAAe8A/i2oRmALiO8cB3sEzDosBxyZyFg4KK5rAXoBy0/2EfQAAADAAADAAADAAADAAADAAADAAJq", 140, nalu_0, &nalu_0_size) != CHIAKI_ERR_SUCCESS || nalu_0_size != 105) return MUNIT_ERROR;
@ -17,7 +19,7 @@ uint8_t nalu_0[105]; size_t nalu_0_size = sizeof(nalu_0); if(chiaki_base64_decod
ChiakiTakionAVPacket av_packet_0;
memset(&av_packet_0, 0, sizeof(av_packet_0));
chiaki_takion_v9_av_packet_parse(&av_packet_0, packet_0, sizeof(packet_0));
chiaki_takion_v9_av_packet_parse(&av_packet_0, &key_state, packet_0, sizeof(packet_0));
munit_assert(av_packet_0.is_video);
munit_assert_size(av_packet_0.data_size, ==, sizeof(nalu_0));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_0.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_0.data, av_packet_0.data_size);
@ -30,7 +32,7 @@ uint8_t nalu_1[108]; size_t nalu_1_size = sizeof(nalu_1); if(chiaki_base64_decod
ChiakiTakionAVPacket av_packet_1;
memset(&av_packet_1, 0, sizeof(av_packet_1));
chiaki_takion_v9_av_packet_parse(&av_packet_1, packet_1, sizeof(packet_1));
chiaki_takion_v9_av_packet_parse(&av_packet_1, &key_state, packet_1, sizeof(packet_1));
munit_assert(av_packet_1.is_video);
munit_assert_size(av_packet_1.data_size, ==, sizeof(nalu_1));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_1.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_1.data, av_packet_1.data_size);
@ -43,7 +45,7 @@ uint8_t nalu_2[1400]; size_t nalu_2_size = sizeof(nalu_2); if(chiaki_base64_deco
ChiakiTakionAVPacket av_packet_2;
memset(&av_packet_2, 0, sizeof(av_packet_2));
chiaki_takion_v9_av_packet_parse(&av_packet_2, packet_2, sizeof(packet_2));
chiaki_takion_v9_av_packet_parse(&av_packet_2, &key_state, packet_2, sizeof(packet_2));
munit_assert(av_packet_2.is_video);
munit_assert_size(av_packet_2.data_size, ==, sizeof(nalu_2));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_2.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_2.data, av_packet_2.data_size);
@ -56,7 +58,7 @@ uint8_t nalu_3[12]; size_t nalu_3_size = sizeof(nalu_3); if(chiaki_base64_decode
ChiakiTakionAVPacket av_packet_3;
memset(&av_packet_3, 0, sizeof(av_packet_3));
chiaki_takion_v9_av_packet_parse(&av_packet_3, packet_3, sizeof(packet_3));
chiaki_takion_v9_av_packet_parse(&av_packet_3, &key_state, packet_3, sizeof(packet_3));
munit_assert(av_packet_3.is_video);
munit_assert_size(av_packet_3.data_size, ==, sizeof(nalu_3));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_3.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_3.data, av_packet_3.data_size);
@ -69,7 +71,7 @@ uint8_t nalu_4[1400]; size_t nalu_4_size = sizeof(nalu_4); if(chiaki_base64_deco
ChiakiTakionAVPacket av_packet_4;
memset(&av_packet_4, 0, sizeof(av_packet_4));
chiaki_takion_v9_av_packet_parse(&av_packet_4, packet_4, sizeof(packet_4));
chiaki_takion_v9_av_packet_parse(&av_packet_4, &key_state, packet_4, sizeof(packet_4));
munit_assert(av_packet_4.is_video);
munit_assert_size(av_packet_4.data_size, ==, sizeof(nalu_4));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_4.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_4.data, av_packet_4.data_size);
@ -82,7 +84,7 @@ uint8_t nalu_5[139]; size_t nalu_5_size = sizeof(nalu_5); if(chiaki_base64_decod
ChiakiTakionAVPacket av_packet_5;
memset(&av_packet_5, 0, sizeof(av_packet_5));
chiaki_takion_v9_av_packet_parse(&av_packet_5, packet_5, sizeof(packet_5));
chiaki_takion_v9_av_packet_parse(&av_packet_5, &key_state, packet_5, sizeof(packet_5));
munit_assert(av_packet_5.is_video);
munit_assert_size(av_packet_5.data_size, ==, sizeof(nalu_5));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_5.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_5.data, av_packet_5.data_size);
@ -95,7 +97,7 @@ uint8_t nalu_6[1339]; size_t nalu_6_size = sizeof(nalu_6); if(chiaki_base64_deco
ChiakiTakionAVPacket av_packet_6;
memset(&av_packet_6, 0, sizeof(av_packet_6));
chiaki_takion_v9_av_packet_parse(&av_packet_6, packet_6, sizeof(packet_6));
chiaki_takion_v9_av_packet_parse(&av_packet_6, &key_state, packet_6, sizeof(packet_6));
munit_assert(av_packet_6.is_video);
munit_assert_size(av_packet_6.data_size, ==, sizeof(nalu_6));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_6.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_6.data, av_packet_6.data_size);
@ -108,7 +110,7 @@ uint8_t nalu_7[1400]; size_t nalu_7_size = sizeof(nalu_7); if(chiaki_base64_deco
ChiakiTakionAVPacket av_packet_7;
memset(&av_packet_7, 0, sizeof(av_packet_7));
chiaki_takion_v9_av_packet_parse(&av_packet_7, packet_7, sizeof(packet_7));
chiaki_takion_v9_av_packet_parse(&av_packet_7, &key_state, packet_7, sizeof(packet_7));
munit_assert(av_packet_7.is_video);
munit_assert_size(av_packet_7.data_size, ==, sizeof(nalu_7));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_7.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_7.data, av_packet_7.data_size);
@ -121,7 +123,7 @@ uint8_t nalu_8[172]; size_t nalu_8_size = sizeof(nalu_8); if(chiaki_base64_decod
ChiakiTakionAVPacket av_packet_8;
memset(&av_packet_8, 0, sizeof(av_packet_8));
chiaki_takion_v9_av_packet_parse(&av_packet_8, packet_8, sizeof(packet_8));
chiaki_takion_v9_av_packet_parse(&av_packet_8, &key_state, packet_8, sizeof(packet_8));
munit_assert(av_packet_8.is_video);
munit_assert_size(av_packet_8.data_size, ==, sizeof(nalu_8));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_8.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_8.data, av_packet_8.data_size);
@ -134,7 +136,7 @@ uint8_t nalu_9[1351]; size_t nalu_9_size = sizeof(nalu_9); if(chiaki_base64_deco
ChiakiTakionAVPacket av_packet_9;
memset(&av_packet_9, 0, sizeof(av_packet_9));
chiaki_takion_v9_av_packet_parse(&av_packet_9, packet_9, sizeof(packet_9));
chiaki_takion_v9_av_packet_parse(&av_packet_9, &key_state, packet_9, sizeof(packet_9));
munit_assert(av_packet_9.is_video);
munit_assert_size(av_packet_9.data_size, ==, sizeof(nalu_9));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_9.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_9.data, av_packet_9.data_size);
@ -147,7 +149,7 @@ uint8_t nalu_10[1400]; size_t nalu_10_size = sizeof(nalu_10); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_10;
memset(&av_packet_10, 0, sizeof(av_packet_10));
chiaki_takion_v9_av_packet_parse(&av_packet_10, packet_10, sizeof(packet_10));
chiaki_takion_v9_av_packet_parse(&av_packet_10, &key_state, packet_10, sizeof(packet_10));
munit_assert(av_packet_10.is_video);
munit_assert_size(av_packet_10.data_size, ==, sizeof(nalu_10));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_10.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_10.data, av_packet_10.data_size);
@ -160,7 +162,7 @@ uint8_t nalu_11[11]; size_t nalu_11_size = sizeof(nalu_11); if(chiaki_base64_dec
ChiakiTakionAVPacket av_packet_11;
memset(&av_packet_11, 0, sizeof(av_packet_11));
chiaki_takion_v9_av_packet_parse(&av_packet_11, packet_11, sizeof(packet_11));
chiaki_takion_v9_av_packet_parse(&av_packet_11, &key_state, packet_11, sizeof(packet_11));
munit_assert(av_packet_11.is_video);
munit_assert_size(av_packet_11.data_size, ==, sizeof(nalu_11));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_11.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_11.data, av_packet_11.data_size);
@ -173,7 +175,7 @@ uint8_t nalu_12[1400]; size_t nalu_12_size = sizeof(nalu_12); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_12;
memset(&av_packet_12, 0, sizeof(av_packet_12));
chiaki_takion_v9_av_packet_parse(&av_packet_12, packet_12, sizeof(packet_12));
chiaki_takion_v9_av_packet_parse(&av_packet_12, &key_state, packet_12, sizeof(packet_12));
munit_assert(av_packet_12.is_video);
munit_assert_size(av_packet_12.data_size, ==, sizeof(nalu_12));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_12.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_12.data, av_packet_12.data_size);
@ -186,7 +188,7 @@ uint8_t nalu_13[10]; size_t nalu_13_size = sizeof(nalu_13); if(chiaki_base64_dec
ChiakiTakionAVPacket av_packet_13;
memset(&av_packet_13, 0, sizeof(av_packet_13));
chiaki_takion_v9_av_packet_parse(&av_packet_13, packet_13, sizeof(packet_13));
chiaki_takion_v9_av_packet_parse(&av_packet_13, &key_state, packet_13, sizeof(packet_13));
munit_assert(av_packet_13.is_video);
munit_assert_size(av_packet_13.data_size, ==, sizeof(nalu_13));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_13.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_13.data, av_packet_13.data_size);
@ -199,7 +201,7 @@ uint8_t nalu_14[1378]; size_t nalu_14_size = sizeof(nalu_14); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_14;
memset(&av_packet_14, 0, sizeof(av_packet_14));
chiaki_takion_v9_av_packet_parse(&av_packet_14, packet_14, sizeof(packet_14));
chiaki_takion_v9_av_packet_parse(&av_packet_14, &key_state, packet_14, sizeof(packet_14));
munit_assert(av_packet_14.is_video);
munit_assert_size(av_packet_14.data_size, ==, sizeof(nalu_14));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_14.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_14.data, av_packet_14.data_size);
@ -212,7 +214,7 @@ uint8_t nalu_15[1353]; size_t nalu_15_size = sizeof(nalu_15); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_15;
memset(&av_packet_15, 0, sizeof(av_packet_15));
chiaki_takion_v9_av_packet_parse(&av_packet_15, packet_15, sizeof(packet_15));
chiaki_takion_v9_av_packet_parse(&av_packet_15, &key_state, packet_15, sizeof(packet_15));
munit_assert(av_packet_15.is_video);
munit_assert_size(av_packet_15.data_size, ==, sizeof(nalu_15));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_15.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_15.data, av_packet_15.data_size);
@ -225,7 +227,7 @@ uint8_t nalu_16[1332]; size_t nalu_16_size = sizeof(nalu_16); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_16;
memset(&av_packet_16, 0, sizeof(av_packet_16));
chiaki_takion_v9_av_packet_parse(&av_packet_16, packet_16, sizeof(packet_16));
chiaki_takion_v9_av_packet_parse(&av_packet_16, &key_state, packet_16, sizeof(packet_16));
munit_assert(av_packet_16.is_video);
munit_assert_size(av_packet_16.data_size, ==, sizeof(nalu_16));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_16.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_16.data, av_packet_16.data_size);
@ -238,7 +240,7 @@ uint8_t nalu_17[1357]; size_t nalu_17_size = sizeof(nalu_17); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_17;
memset(&av_packet_17, 0, sizeof(av_packet_17));
chiaki_takion_v9_av_packet_parse(&av_packet_17, packet_17, sizeof(packet_17));
chiaki_takion_v9_av_packet_parse(&av_packet_17, &key_state, packet_17, sizeof(packet_17));
munit_assert(av_packet_17.is_video);
munit_assert_size(av_packet_17.data_size, ==, sizeof(nalu_17));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_17.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_17.data, av_packet_17.data_size);
@ -254,7 +256,7 @@ uint8_t nalu_18[575]; size_t nalu_18_size = sizeof(nalu_18); if(chiaki_base64_de
ChiakiTakionAVPacket av_packet_18;
memset(&av_packet_18, 0, sizeof(av_packet_18));
chiaki_takion_v9_av_packet_parse(&av_packet_18, packet_18, sizeof(packet_18));
chiaki_takion_v9_av_packet_parse(&av_packet_18, &key_state, packet_18, sizeof(packet_18));
munit_assert(av_packet_18.is_video);
munit_assert_size(av_packet_18.data_size, ==, sizeof(nalu_18));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_18.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_18.data, av_packet_18.data_size);
@ -267,7 +269,7 @@ uint8_t nalu_19[1400]; size_t nalu_19_size = sizeof(nalu_19); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_19;
memset(&av_packet_19, 0, sizeof(av_packet_19));
chiaki_takion_v9_av_packet_parse(&av_packet_19, packet_19, sizeof(packet_19));
chiaki_takion_v9_av_packet_parse(&av_packet_19, &key_state, packet_19, sizeof(packet_19));
munit_assert(av_packet_19.is_video);
munit_assert_size(av_packet_19.data_size, ==, sizeof(nalu_19));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_19.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_19.data, av_packet_19.data_size);
@ -280,7 +282,7 @@ uint8_t nalu_20[1328]; size_t nalu_20_size = sizeof(nalu_20); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_20;
memset(&av_packet_20, 0, sizeof(av_packet_20));
chiaki_takion_v9_av_packet_parse(&av_packet_20, packet_20, sizeof(packet_20));
chiaki_takion_v9_av_packet_parse(&av_packet_20, &key_state, packet_20, sizeof(packet_20));
munit_assert(av_packet_20.is_video);
munit_assert_size(av_packet_20.data_size, ==, sizeof(nalu_20));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_20.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_20.data, av_packet_20.data_size);
@ -293,7 +295,7 @@ uint8_t nalu_21[1313]; size_t nalu_21_size = sizeof(nalu_21); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_21;
memset(&av_packet_21, 0, sizeof(av_packet_21));
chiaki_takion_v9_av_packet_parse(&av_packet_21, packet_21, sizeof(packet_21));
chiaki_takion_v9_av_packet_parse(&av_packet_21, &key_state, packet_21, sizeof(packet_21));
munit_assert(av_packet_21.is_video);
munit_assert_size(av_packet_21.data_size, ==, sizeof(nalu_21));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_21.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_21.data, av_packet_21.data_size);
@ -306,7 +308,7 @@ uint8_t nalu_22[1331]; size_t nalu_22_size = sizeof(nalu_22); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_22;
memset(&av_packet_22, 0, sizeof(av_packet_22));
chiaki_takion_v9_av_packet_parse(&av_packet_22, packet_22, sizeof(packet_22));
chiaki_takion_v9_av_packet_parse(&av_packet_22, &key_state, packet_22, sizeof(packet_22));
munit_assert(av_packet_22.is_video);
munit_assert_size(av_packet_22.data_size, ==, sizeof(nalu_22));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_22.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_22.data, av_packet_22.data_size);
@ -319,7 +321,7 @@ uint8_t nalu_23[1307]; size_t nalu_23_size = sizeof(nalu_23); if(chiaki_base64_d
ChiakiTakionAVPacket av_packet_23;
memset(&av_packet_23, 0, sizeof(av_packet_23));
chiaki_takion_v9_av_packet_parse(&av_packet_23, packet_23, sizeof(packet_23));
chiaki_takion_v9_av_packet_parse(&av_packet_23, &key_state, packet_23, sizeof(packet_23));
munit_assert(av_packet_23.is_video);
munit_assert_size(av_packet_23.data_size, ==, sizeof(nalu_23));
chiaki_gkcrypt_decrypt(&gkcrypt, av_packet_23.key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, av_packet_23.data, av_packet_23.data_size);