#include #include #include "crypto_aes_algo.h" #define BLOCK_SIZE 16 static struct aes_state st; int flag = 0; bool iv_set = 0; ut8 iv[32]; static int aes_cbc_set_key(RCrypto *cry, const ut8 *key, int keylen, int mode, int direction) { if (!(keylen == 128 / 8 || keylen == 192 / 8 || keylen == 256 / 8)) { return false; } st.key_size = keylen; st.rounds = 6 + (int)(keylen / 4); st.columns = (int)(keylen / 4); memcpy (st.key, key, keylen); flag = direction; return true; } static int aes_cbc_get_key_size(RCrypto *cry) { return st.key_size; } static int aes_cbc_set_iv(RCrypto *cry, const ut8 *iv_src, int ivlen) { if (ivlen != BLOCK_SIZE) { return false; } memcpy (iv, iv_src, BLOCK_SIZE); iv_set = 1; return true; } static bool aes_cbc_use(const char *algo) { return !strcmp (algo, "aes-cbc"); } static int update(RCrypto *cry, const ut8 *buf, int len) { if (!iv_set) { eprintf ("IV not set. Use -I [iv]\n"); return false; } const int diff = (BLOCK_SIZE - (len % BLOCK_SIZE)) % BLOCK_SIZE; const int size = len + diff; const int blocks = size / BLOCK_SIZE; ut8 *const obuf = calloc (1, size); if (!obuf) return false; ut8 *const ibuf = calloc (1, size); if (!ibuf) { free (obuf); return false; } memset (ibuf, 0, size); memcpy (ibuf, buf, len); if (diff) { ibuf[len] = 8; // 0b1000; } int i, j; if (flag == 0) { for (i = 0; i < blocks; i++) { for (j = 0; j < BLOCK_SIZE; j++) { ibuf[i * BLOCK_SIZE + j] ^= iv[j]; } aes_encrypt (&st, ibuf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i); memcpy (iv, obuf + BLOCK_SIZE * i, BLOCK_SIZE); } } else if (flag == 1) { for (i = 0; i < blocks; i++) { aes_decrypt (&st, ibuf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i); for (j = 0; j < BLOCK_SIZE; j++) { obuf[i * BLOCK_SIZE + j] ^= iv[j]; } memcpy(iv, buf + BLOCK_SIZE * i, BLOCK_SIZE); } } r_crypto_append (cry, obuf, size); free (obuf); free (ibuf); return 0; } static int final(RCrypto *cry, const ut8 *buf, int len) { return update (cry, buf, len); } RCryptoPlugin r_crypto_plugin_aes_cbc = { .name = "aes-cbc", .set_key = aes_cbc_set_key, .get_key_size = aes_cbc_get_key_size, .set_iv = aes_cbc_set_iv, .use = aes_cbc_use, .update = update, .final = final }; #ifndef CORELIB struct r_lib_struct_t radare_plugin = { .type = R_LIB_TYPE_CRYPTO, .data = &r_crypto_plugin_aes_cbc, .version = R2_VERSION }; #endif