From 24adb1fdf7cbb8d84ffed5152063f3e36e0d7635 Mon Sep 17 00:00:00 2001 From: aixiao Date: Fri, 16 Sep 2022 16:52:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E5=91=BD=E4=BB=A4=E8=A7=A3?= =?UTF-8?q?=E5=AF=86=EF=BC=8C=E9=87=87=E7=94=A8=E5=87=BD=E6=95=B0=E8=A7=A3?= =?UTF-8?q?=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 4 +- README.md | 2 - aes.c | 417 ++++++++++++++++++++++++++++++++++ aes.h | 67 ++++++ aes.o | Bin 0 -> 21560 bytes aes/Makefile | 16 -- aes/aes.c | 607 -------------------------------------------------- aes/aes.h | 18 -- aes/main.c | 124 ----------- main.c | 118 +++++++--- main.o | Bin 0 -> 48776 bytes remote_libssh | Bin 0 -> 58792 bytes 12 files changed, 569 insertions(+), 804 deletions(-) create mode 100644 aes.c create mode 100644 aes.h create mode 100644 aes.o delete mode 100644 aes/Makefile delete mode 100644 aes/aes.c delete mode 100644 aes/aes.h delete mode 100644 aes/main.c create mode 100644 main.o create mode 100644 remote_libssh diff --git a/Makefile b/Makefile index 4d77de7..d5ec648 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ CROSS_COMPILE ?= CC := $(CROSS_COMPILE)gcc STRIP := $(CROSS_COMPILE)strip -CFLAGS += -g -O2 -Wall +CFLAGS += -g -Os -Wall LIBS = -lssh OBJ := remote_libssh -all: main.o +all: main.o aes.o $(CC) $(CFLAGS) -o $(OBJ) $^ $(LIBS) .c.o: $(CC) $(CFLAGS) -c $< diff --git a/README.md b/README.md index d30a2da..c549320 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,6 @@ git clone https://git.aixiao.me/aixiao/remote_libssh cd remote_libssh make clean; make - cd ./aes - make clean; make # Help diff --git a/aes.c b/aes.c new file mode 100644 index 0000000..bf77e38 --- /dev/null +++ b/aes.c @@ -0,0 +1,417 @@ +#include + +#include "aes.h" + + + +#define Nb 4 + +#if defined(AES256) && (AES256 == 1) +#define Nk 8 +#define Nr 14 +#elif defined(AES192) && (AES192 == 1) +#define Nk 6 +#define Nr 12 +#else +#define Nk 4 // The number of 32 bit words in a key. +#define Nr 10 // The number of rounds in AES Cipher. +#endif + +#ifndef MULTIPLY_AS_A_FUNCTION +#define MULTIPLY_AS_A_FUNCTION 0 +#endif + +typedef uint8_t state_t[4][4]; + +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 +}; + +#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) +static const uint8_t rsbox[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 +}; +#endif + +static const uint8_t Rcon[11] = { + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 +}; + +#define getSBoxValue(num) (sbox[(num)]) + +static void KeyExpansion(uint8_t * RoundKey, const uint8_t * Key) +{ + unsigned i, j, k; + uint8_t tempa[4]; // Used for the column/row operations + + for (i = 0; i < Nk; ++i) { + RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; + RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; + RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; + RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; + } + + for (i = Nk; i < Nb * (Nr + 1); ++i) { + { + k = (i - 1) * 4; + tempa[0] = RoundKey[k + 0]; + tempa[1] = RoundKey[k + 1]; + tempa[2] = RoundKey[k + 2]; + tempa[3] = RoundKey[k + 3]; + + } + + if (i % Nk == 0) { + { + const uint8_t u8tmp = tempa[0]; + tempa[0] = tempa[1]; + tempa[1] = tempa[2]; + tempa[2] = tempa[3]; + tempa[3] = u8tmp; + } + + { + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + } + + tempa[0] = tempa[0] ^ Rcon[i / Nk]; + } +#if defined(AES256) && (AES256 == 1) + if (i % Nk == 4) { + { + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + } + } +#endif + j = i * 4; + k = (i - Nk) * 4; + RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0]; + RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1]; + RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2]; + RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3]; + } +} + +void AES_init_ctx(struct AES_ctx *ctx, const uint8_t * key) +{ + KeyExpansion(ctx->RoundKey, key); +} + +#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) +void AES_init_ctx_iv(struct AES_ctx *ctx, const uint8_t * key, const uint8_t * iv) +{ + KeyExpansion(ctx->RoundKey, key); + memcpy(ctx->Iv, iv, AES_BLOCKLEN); +} + +void AES_ctx_set_iv(struct AES_ctx *ctx, const uint8_t * iv) +{ + memcpy(ctx->Iv, iv, AES_BLOCKLEN); +} +#endif + +static void AddRoundKey(uint8_t round, state_t * state, const uint8_t * RoundKey) +{ + uint8_t i, j; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j]; + } + } +} + +static void SubBytes(state_t * state) +{ + uint8_t i, j; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + (*state)[j][i] = getSBoxValue((*state)[j][i]); + } + } +} + +static void ShiftRows(state_t * state) +{ + uint8_t temp; + + temp = (*state)[0][1]; + (*state)[0][1] = (*state)[1][1]; + (*state)[1][1] = (*state)[2][1]; + (*state)[2][1] = (*state)[3][1]; + (*state)[3][1] = temp; + + temp = (*state)[0][2]; + (*state)[0][2] = (*state)[2][2]; + (*state)[2][2] = temp; + + temp = (*state)[1][2]; + (*state)[1][2] = (*state)[3][2]; + (*state)[3][2] = temp; + + temp = (*state)[0][3]; + (*state)[0][3] = (*state)[3][3]; + (*state)[3][3] = (*state)[2][3]; + (*state)[2][3] = (*state)[1][3]; + (*state)[1][3] = temp; +} + +static uint8_t xtime(uint8_t x) +{ + return ((x << 1) ^ (((x >> 7) & 1) * 0x1b)); +} + +static void MixColumns(state_t * state) +{ + uint8_t i; + uint8_t Tmp, Tm, t; + for (i = 0; i < 4; ++i) { + t = (*state)[i][0]; + Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3]; + Tm = (*state)[i][0] ^ (*state)[i][1]; + Tm = xtime(Tm); + (*state)[i][0] ^= Tm ^ Tmp; + Tm = (*state)[i][1] ^ (*state)[i][2]; + Tm = xtime(Tm); + (*state)[i][1] ^= Tm ^ Tmp; + Tm = (*state)[i][2] ^ (*state)[i][3]; + Tm = xtime(Tm); + (*state)[i][2] ^= Tm ^ Tmp; + Tm = (*state)[i][3] ^ t; + Tm = xtime(Tm); + (*state)[i][3] ^= Tm ^ Tmp; + } +} + +#if MULTIPLY_AS_A_FUNCTION +static uint8_t Multiply(uint8_t x, uint8_t y) +{ + return (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^ ((y >> 2 & 1) * xtime(xtime(x))) ^ ((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^ ((y >> 4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */ +} +#else +#define Multiply(x, y) \ + ( ((y & 1) * x) ^ \ + ((y>>1 & 1) * xtime(x)) ^ \ + ((y>>2 & 1) * xtime(xtime(x))) ^ \ + ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \ + ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \ + +#endif + +#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) + +#define getSBoxInvert(num) (rsbox[(num)]) + +static void InvMixColumns(state_t * state) +{ + int i; + uint8_t a, b, c, d; + for (i = 0; i < 4; ++i) { + a = (*state)[i][0]; + b = (*state)[i][1]; + c = (*state)[i][2]; + d = (*state)[i][3]; + + (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); + (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); + (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); + (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); + } +} + +static void InvSubBytes(state_t * state) +{ + uint8_t i, j; + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + (*state)[j][i] = getSBoxInvert((*state)[j][i]); + } + } +} + +static void InvShiftRows(state_t * state) +{ + uint8_t temp; + + temp = (*state)[3][1]; + (*state)[3][1] = (*state)[2][1]; + (*state)[2][1] = (*state)[1][1]; + (*state)[1][1] = (*state)[0][1]; + (*state)[0][1] = temp; + + temp = (*state)[0][2]; + (*state)[0][2] = (*state)[2][2]; + (*state)[2][2] = temp; + + temp = (*state)[1][2]; + (*state)[1][2] = (*state)[3][2]; + (*state)[3][2] = temp; + + temp = (*state)[0][3]; + (*state)[0][3] = (*state)[1][3]; + (*state)[1][3] = (*state)[2][3]; + (*state)[2][3] = (*state)[3][3]; + (*state)[3][3] = temp; +} +#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) + +static void Cipher(state_t * state, const uint8_t * RoundKey) +{ + uint8_t round = 0; + + AddRoundKey(0, state, RoundKey); + + for (round = 1;; ++round) { + SubBytes(state); + ShiftRows(state); + if (round == Nr) { + break; + } + MixColumns(state); + AddRoundKey(round, state, RoundKey); + } + AddRoundKey(Nr, state, RoundKey); +} + +#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) +static void InvCipher(state_t * state, const uint8_t * RoundKey) +{ + uint8_t round = 0; + + AddRoundKey(Nr, state, RoundKey); + + for (round = (Nr - 1);; --round) { + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(round, state, RoundKey); + if (round == 0) { + break; + } + InvMixColumns(state); + } + +} +#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) + +#if defined(ECB) && (ECB == 1) + +void AES_ECB_encrypt(const struct AES_ctx *ctx, uint8_t * buf) +{ + Cipher((state_t *) buf, ctx->RoundKey); +} + +void AES_ECB_decrypt(const struct AES_ctx *ctx, uint8_t * buf) +{ + // The next function call decrypts the PlainText with the Key using AES algorithm. + InvCipher((state_t *) buf, ctx->RoundKey); +} + +#endif // #if defined(ECB) && (ECB == 1) + +#if defined(CBC) && (CBC == 1) + +static void XorWithIv(uint8_t * buf, const uint8_t * Iv) +{ + uint8_t i; + for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size + { + buf[i] ^= Iv[i]; + } +} + +void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t * buf, size_t length) +{ + size_t i; + uint8_t *Iv = ctx->Iv; + for (i = 0; i < length; i += AES_BLOCKLEN) { + XorWithIv(buf, Iv); + Cipher((state_t *) buf, ctx->RoundKey); + Iv = buf; + buf += AES_BLOCKLEN; + } + /* store Iv in ctx for next call */ + memcpy(ctx->Iv, Iv, AES_BLOCKLEN); +} + +void AES_CBC_decrypt_buffer(struct AES_ctx *ctx, uint8_t * buf, size_t length) +{ + size_t i; + uint8_t storeNextIv[AES_BLOCKLEN]; + for (i = 0; i < length; i += AES_BLOCKLEN) { + memcpy(storeNextIv, buf, AES_BLOCKLEN); + InvCipher((state_t *) buf, ctx->RoundKey); + XorWithIv(buf, ctx->Iv); + memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); + buf += AES_BLOCKLEN; + } + +} + +#endif // #if defined(CBC) && (CBC == 1) + +#if defined(CTR) && (CTR == 1) + +void AES_CTR_xcrypt_buffer(struct AES_ctx *ctx, uint8_t * buf, size_t length) +{ + uint8_t buffer[AES_BLOCKLEN]; + + size_t i; + int bi; + for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi) { + if (bi == AES_BLOCKLEN) { /* we need to regen xor compliment in buffer */ + memcpy(buffer, ctx->Iv, AES_BLOCKLEN); + Cipher((state_t *) buffer, ctx->RoundKey); + + /* Increment Iv and handle overflow */ + for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi) { + /* inc will overflow */ + if (ctx->Iv[bi] == 255) { + ctx->Iv[bi] = 0; + continue; + } + ctx->Iv[bi] += 1; + break; + } + bi = 0; + } + + buf[i] = (buf[i] ^ buffer[bi]); + } +} + +#endif // #if defined(CTR) && (CTR == 1) diff --git a/aes.h b/aes.h new file mode 100644 index 0000000..d905832 --- /dev/null +++ b/aes.h @@ -0,0 +1,67 @@ +#ifndef _AES_H_ +#define _AES_H_ + +#include +#include + +#ifndef CBC +#define CBC 1 +#endif + +#ifndef ECB +#define ECB 1 +#endif + +#ifndef CTR +#define CTR 1 +#endif + +#define AES128 1 +//#define AES192 1 +//#define AES256 1 + +#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only + +#if defined(AES256) && (AES256 == 1) +#define AES_KEYLEN 32 +#define AES_keyExpSize 240 +#elif defined(AES192) && (AES192 == 1) +#define AES_KEYLEN 24 +#define AES_keyExpSize 208 +#else +#define AES_KEYLEN 16 // Key length in bytes +#define AES_keyExpSize 176 +#endif + +struct AES_ctx { + uint8_t RoundKey[AES_keyExpSize]; +#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) + uint8_t Iv[AES_BLOCKLEN]; +#endif +}; + +void AES_init_ctx(struct AES_ctx *ctx, const uint8_t * key); +#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) +void AES_init_ctx_iv(struct AES_ctx *ctx, const uint8_t * key, const uint8_t * iv); +void AES_ctx_set_iv(struct AES_ctx *ctx, const uint8_t * iv); +#endif + +#if defined(ECB) && (ECB == 1) +void AES_ECB_encrypt(const struct AES_ctx *ctx, uint8_t * buf); +void AES_ECB_decrypt(const struct AES_ctx *ctx, uint8_t * buf); + +#endif // #if defined(ECB) && (ECB == !) + +#if defined(CBC) && (CBC == 1) +void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t * buf, size_t length); +void AES_CBC_decrypt_buffer(struct AES_ctx *ctx, uint8_t * buf, size_t length); + +#endif // #if defined(CBC) && (CBC == 1) + +#if defined(CTR) && (CTR == 1) + +void AES_CTR_xcrypt_buffer(struct AES_ctx *ctx, uint8_t * buf, size_t length); + +#endif // #if defined(CTR) && (CTR == 1) + +#endif // _AES_H_ diff --git a/aes.o b/aes.o new file mode 100644 index 0000000000000000000000000000000000000000..6a9848ddb2e02a3e99741a57c904a5f1d086d8d1 GIT binary patch literal 21560 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 1; - } - - return (uint8_t)p; -} - -/* - * Addition of 4 byte words - * m(x) = x4+1 - */ -void coef_add(uint8_t a[], uint8_t b[], uint8_t d[]) -{ - - d[0] = a[0]^b[0]; - d[1] = a[1]^b[1]; - d[2] = a[2]^b[2]; - d[3] = a[3]^b[3]; -} - -/* - * Multiplication of 4 byte words - * m(x) = x4+1 - */ -void coef_mult(uint8_t *a, uint8_t *b, uint8_t *d) -{ - - d[0] = gmult(a[0],b[0])^gmult(a[3],b[1])^gmult(a[2],b[2])^gmult(a[1],b[3]); - d[1] = gmult(a[1],b[0])^gmult(a[0],b[1])^gmult(a[3],b[2])^gmult(a[2],b[3]); - d[2] = gmult(a[2],b[0])^gmult(a[1],b[1])^gmult(a[0],b[2])^gmult(a[3],b[3]); - d[3] = gmult(a[3],b[0])^gmult(a[2],b[1])^gmult(a[1],b[2])^gmult(a[0],b[3]); -} - -/* - * S-box transformation table - */ -static uint8_t s_box[256] = -{ - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, // 0 - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, // 1 - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, // 2 - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, // 3 - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, // 4 - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, // 5 - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, // 6 - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, // 7 - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, // 8 - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, // 9 - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, // a - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, // b - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, // c - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, // d - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, // e - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -};// f - -/* - * Inverse S-box transformation table - */ -static uint8_t inv_s_box[256] = -{ - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, // 0 - 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, // 1 - 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, // 2 - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, // 3 - 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, // 4 - 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, // 5 - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, // 6 - 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, // 7 - 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, // 8 - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, // 9 - 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, // a - 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, // b - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, // c - 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, // d - 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, // e - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d -};// f - - -/* - * Generates the round constant Rcon[i] - */ -uint8_t R[] = {0x02, 0x00, 0x00, 0x00}; - -uint8_t * Rcon(uint8_t i) -{ - - if (i == 1) - { - R[0] = 0x01; // x^(1-1) = x^0 = 1 - } - else if (i > 1) - { - R[0] = 0x02; - i--; - while (i-1 > 0) - { - R[0] = gmult(R[0], 0x02); - i--; - } - } - - return R; -} - -/* - * Transformation in the Cipher and Inverse Cipher in which a Round - * Key is added to the State using an XOR operation. The length of a - * Round Key equals the size of the State (i.e., for Nb = 4, the Round - * Key length equals 128 bits/16 bytes). - */ -void add_round_key(uint8_t *state, uint8_t *w, uint8_t r) -{ - - uint8_t c; - - for (c = 0; c < Nb; c++) - { - state[Nb*0+c] = state[Nb*0+c]^w[4*Nb*r+4*c+0]; //debug, so it works for Nb !=4 - state[Nb*1+c] = state[Nb*1+c]^w[4*Nb*r+4*c+1]; - state[Nb*2+c] = state[Nb*2+c]^w[4*Nb*r+4*c+2]; - state[Nb*3+c] = state[Nb*3+c]^w[4*Nb*r+4*c+3]; - } -} - -/* - * Transformation in the Cipher that takes all of the columns of the - * State and mixes their data (independently of one another) to - * produce new columns. - */ -void mix_columns(uint8_t *state) -{ - - uint8_t a[] = {0x02, 0x01, 0x01, 0x03}; // a(x) = {02} + {01}x + {01}x2 + {03}x3 - uint8_t i, j, col[4], res[4]; - - for (j = 0; j < Nb; j++) - { - for (i = 0; i < 4; i++) - { - col[i] = state[Nb*i+j]; - } - - coef_mult(a, col, res); - - for (i = 0; i < 4; i++) - { - state[Nb*i+j] = res[i]; - } - } -} - -/* - * Transformation in the Inverse Cipher that is the inverse of - * MixColumns(). - */ -void inv_mix_columns(uint8_t *state) -{ - - uint8_t a[] = {0x0e, 0x09, 0x0d, 0x0b}; // a(x) = {0e} + {09}x + {0d}x2 + {0b}x3 - uint8_t i, j, col[4], res[4]; - - for (j = 0; j < Nb; j++) - { - for (i = 0; i < 4; i++) - { - col[i] = state[Nb*i+j]; - } - - coef_mult(a, col, res); - - for (i = 0; i < 4; i++) - { - state[Nb*i+j] = res[i]; - } - } -} - -/* - * Transformation in the Cipher that processes the State by cyclically - * shifting the last three rows of the State by different offsets. - */ -void shift_rows(uint8_t *state) -{ - - uint8_t i, k, s, tmp; - - for (i = 1; i < 4; i++) - { - // shift(1,4)=1; shift(2,4)=2; shift(3,4)=3 - // shift(r, 4) = r; - s = 0; - while (s < i) - { - tmp = state[Nb*i+0]; - - for (k = 1; k < Nb; k++) - { - state[Nb*i+k-1] = state[Nb*i+k]; - } - - state[Nb*i+Nb-1] = tmp; - s++; - } - } -} - -/* - * Transformation in the Inverse Cipher that is the inverse of - * ShiftRows(). - */ -void inv_shift_rows(uint8_t *state) -{ - - uint8_t i, k, s, tmp; - - for (i = 1; i < 4; i++) - { - s = 0; - while (s < i) - { - tmp = state[Nb*i+Nb-1]; - - for (k = Nb-1; k > 0; k--) - { - state[Nb*i+k] = state[Nb*i+k-1]; - } - - state[Nb*i+0] = tmp; - s++; - } - } -} - -/* - * Transformation in the Cipher that processes the State using a non­ - * linear byte substitution table (S-box) that operates on each of the - * State bytes independently. - */ -void sub_bytes(uint8_t *state) -{ - - uint8_t i, j; - uint8_t row, col; - - for (i = 0; i < 4; i++) - { - for (j = 0; j < Nb; j++) - { - row = (state[Nb*i+j] & 0xf0) >> 4; - col = state[Nb*i+j] & 0x0f; - state[Nb*i+j] = s_box[16*row+col]; - } - } -} - -/* - * Transformation in the Inverse Cipher that is the inverse of - * SubBytes(). - */ -void inv_sub_bytes(uint8_t *state) -{ - - uint8_t i, j; - uint8_t row, col; - - for (i = 0; i < 4; i++) - { - for (j = 0; j < Nb; j++) - { - row = (state[Nb*i+j] & 0xf0) >> 4; - col = state[Nb*i+j] & 0x0f; - state[Nb*i+j] = inv_s_box[16*row+col]; - } - } -} - -/* - * Function used in the Key Expansion routine that takes a four-byte - * input word and applies an S-box to each of the four bytes to - * produce an output word. - */ -void sub_word(uint8_t *w) -{ - - uint8_t i; - - for (i = 0; i < 4; i++) - { - w[i] = s_box[16*((w[i] & 0xf0) >> 4) + (w[i] & 0x0f)]; - } -} - -/* - * Function used in the Key Expansion routine that takes a four-byte - * word and performs a cyclic permutation. - */ -void rot_word(uint8_t *w) -{ - - uint8_t tmp; - uint8_t i; - - tmp = w[0]; - - for (i = 0; i < 3; i++) - { - w[i] = w[i+1]; - } - - w[3] = tmp; -} - -/* - * Key Expansion - */ -void key_expansion(uint8_t *key, uint8_t *w) -{ - - uint8_t tmp[4]; - uint8_t i; - uint8_t len = Nb*(Nr+1); - - for (i = 0; i < Nk; i++) - { - w[4*i+0] = key[4*i+0]; - w[4*i+1] = key[4*i+1]; - w[4*i+2] = key[4*i+2]; - w[4*i+3] = key[4*i+3]; - } - - for (i = Nk; i < len; i++) - { - tmp[0] = w[4*(i-1)+0]; - tmp[1] = w[4*(i-1)+1]; - tmp[2] = w[4*(i-1)+2]; - tmp[3] = w[4*(i-1)+3]; - - if (i%Nk == 0) - { - - rot_word(tmp); - sub_word(tmp); - coef_add(tmp, Rcon(i/Nk), tmp); - - } - else if (Nk > 6 && i%Nk == 4) - { - - sub_word(tmp); - - } - - w[4*i+0] = w[4*(i-Nk)+0]^tmp[0]; - w[4*i+1] = w[4*(i-Nk)+1]^tmp[1]; - w[4*i+2] = w[4*(i-Nk)+2]^tmp[2]; - w[4*i+3] = w[4*(i-Nk)+3]^tmp[3]; - } -} - -void cipher(uint8_t *in, uint8_t *out, uint8_t *w) -{ - - uint8_t state[4*Nb]; - uint8_t r, i, j; - - for (i = 0; i < 4; i++) - { - for (j = 0; j < Nb; j++) - { - state[Nb*i+j] = in[i+4*j]; - } - } - - add_round_key(state, w, 0); - - for (r = 1; r < Nr; r++) - { - sub_bytes(state); - shift_rows(state); - mix_columns(state); - add_round_key(state, w, r); - } - - sub_bytes(state); - shift_rows(state); - add_round_key(state, w, Nr); - - for (i = 0; i < 4; i++) - { - for (j = 0; j < Nb; j++) - { - out[i+4*j] = state[Nb*i+j]; - } - } -} - -void inv_cipher(uint8_t *in, uint8_t *out, uint8_t *w) -{ - - uint8_t state[4*Nb]; - uint8_t r, i, j; - - for (i = 0; i < 4; i++) - { - for (j = 0; j < Nb; j++) - { - state[Nb*i+j] = in[i+4*j]; - } - } - - add_round_key(state, w, Nr); - - for (r = Nr-1; r >= 1; r--) - { - inv_shift_rows(state); - inv_sub_bytes(state); - add_round_key(state, w, r); - inv_mix_columns(state); - } - - inv_shift_rows(state); - inv_sub_bytes(state); - add_round_key(state, w, 0); - - for (i = 0; i < 4; i++) - { - for (j = 0; j < Nb; j++) - { - out[i+4*j] = state[Nb*i+j]; - } - } -} - -/*******************结束*********************/ - -//将原始string转换为密文 -//原始数据长度: orign -//加密后的数据:text -bool EncryptDataToCipherTxt(uint8_t *orign, uint8_t *result, uint16_t length) -{ - uint8_t w[240]; //密钥扩展,定义最大长度 - - //根据密钥长度计算Nk,Nr - switch (sizeof(key)) - { - default: - case 16: - Nk = 4; - Nr = 10; - break; - case 24: - Nk = 6; - Nr = 12; - break; - case 32: - Nk = 8; - Nr = 14; - break; - } - - //计算出扩展密钥的值 - key_expansion(key, w); - - //分块加密,每段16字节 - if( length % 16 == 0 ) - { - uint16_t i; - uint16_t counter=length / 16; - uint8_t *p,*q; - - for(i=0; i -#include -#include -#include -#include - -extern uint8_t *key; - -//加密 -bool EncryptDataToCipherTxt(uint8_t *orign, uint8_t *result, uint16_t length); - -//解密 -bool DecryptCipherTxtToData(uint8_t *orign, uint8_t *result, uint16_t length); - -#endif diff --git a/aes/main.c b/aes/main.c deleted file mode 100644 index 9f0dd17..0000000 --- a/aes/main.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include -#include "aes.h" - -#define AES_ENC_MAX_LEN 8192 - -uint8_t *key; - -void from_hex(char *s, int l, char *d) -{ - while (l--) { - *(d++) = ((*s > '9' ? (*(s++) + 9) : *(s++)) << 4) - | ((*s > '9' ? (*(s++) + 9) : *(s++)) & 0x0F); - } -} - -void StringToByte(char *source, unsigned char *dest, int sourceLen) -{ - - int i; - unsigned char highByte, lowByte; - - for (i = 0; i < sourceLen; i += 2) { - highByte = toupper(source[i]); //转换为大写 - lowByte = toupper(source[i + 1]); - - if (highByte > 0x39) - highByte -= 0x37; - else - highByte -= 0x30; - - if (lowByte > 0x39) - lowByte -= 0x37; - else - lowByte -= 0x30; - - dest[i / 2] = (highByte << 4) | lowByte; - } - return; -} - -int array_len(char *str) -{ - int i = 0; - - int Len = strlen(str); - unsigned char out[AES_ENC_MAX_LEN] = { 0 }; - - StringToByte(str, out, Len); - for (i = 0; i < Len / 2; i++) { - ; - //printf("%02X ", out[i]); - } - //printf("%d\n", i); - - return i; -} - -int main(int argc, char *argv[]) -{ - key = (uint8_t *)malloc(128); - strcpy(key, "1234567890ABCDEF"); - char string[AES_ENC_MAX_LEN]; - - int opt; - char optstrs[] = ":e:d:k:h?"; - while (-1 != (opt = getopt(argc, argv, optstrs))) { - switch (opt) { - case 'k': - strcpy(key, optarg); - break; - case 'e': - { - memset(string, 0, AES_ENC_MAX_LEN); - memcpy(string, optarg, strlen(optarg)); - uint16_t i = 0; - uint8_t out[AES_ENC_MAX_LEN]; - - uint16_t length = strlen(string); - - while (length % 16) { - strcat(string, "\0"); - length++; - } - - //printf("加密数据:\n"); - EncryptDataToCipherTxt((uint8_t *) string, out, length); - //printf("密文长度=%d\n", length); - for (i = 0; i < length; i++) { - printf("%02X", out[i]); - } - printf("\n"); - ; - } - break; - case 'd': - { - memset(string, 0x00, AES_ENC_MAX_LEN); - - uint8_t out[AES_ENC_MAX_LEN]; - memset(out, 0x00, AES_ENC_MAX_LEN); - - from_hex(optarg, array_len(optarg), (char *)out); - //printf("%s\n", out); - - DecryptCipherTxtToData(out, (uint8_t *) string, array_len(optarg)); - //printf("解密报文长度=%d\n", array_len(optarg)); - printf("%s\n", string); - } - break; - case ':': - printf("\nMissing argument after: -%c\n", optopt); - case 'h': - case '?': - - default: - ; - } - } - free(key); - return 0; -} diff --git a/main.c b/main.c index 76e1a9d..1f211ec 100644 --- a/main.c +++ b/main.c @@ -3,10 +3,17 @@ #include #include #include +#include #define LIBSSH_STATIC 1 #include +#define CBC 1 +#define CTR 1 +#define ECB 1 + +#include "aes.h" + #define BUFFER_SIZE 1024 int verify_knownhost(ssh_session session) @@ -190,17 +197,13 @@ int show_remote_processes(ssh_session session, char *command, int is) ssh_channel_free(channel); return rc; } - - if (is) - { + + if (is) { interactive_shell_session(session, channel); - } - else - { + } else { execute_remote_command(channel, command); } - ssh_channel_send_eof(channel); ssh_channel_close(channel); ssh_channel_free(channel); @@ -225,31 +228,81 @@ int authenticate_pubkey(ssh_session session, char *priv_name, char *passphrase) return rc; } -int rsa_file() +static int oneHexChar2Hex(char hex) { - char rsa[512] = { 0 }; + int outHex = 0; + if (isdigit(hex)) { + outHex = hex - '0'; + } else if (isupper(hex)) { + outHex = hex - 'A' + 10; + } else { + outHex = hex - 'a' + 10; + } + return outHex; +} - char temp[] = "./aes/aes -d \"FE67236A61D8D67FD4DEBFD46C9E409B94326781DAE97A7DCD84426711D4D0E078EBA98886342F1E8568828843886DCC38487ACDC9C413D73A4E0C80E6070D054FD5E0DCC0771452FC5E31FCF715EFC62177EABE9014E7F9623B4EA843A93A9020A268F9E8A300BB5D30AD22D52F6EA441222205DAF5560A82F18F28075C035205BF4A47E8E350A957B1F7E90AB63AC2FCCCAC23E1C9C3B50F34B32CDBC7BC8B2155475FBC0B794089C60BFA0EFDD2E096D65DAF31A40E31A5D2C1547A4EA622241EEDD9307CB74BFB3C82E5F48FB1A2CA6D5B223BBB9807B6E54487F4F116D7D9EA2320BFE025ED8B88DBF13F79884C8ACB9161793D59D527579319173EC5A0784398C81435FB0536C048AE656F54422BC41207E0DD3E0B66DB70D725B644915D967D9BA56FC9FE1BF8D628D00D5F6835E48CF9C2B9BCB995EC84D881444F0269272FEE8D4FD667A6C909ADB500FB83E25DB45C9CE75044D2C052E72271665BC37AF036D4A81A889BB8A211B4B9730C0ECC9C70B8B4A07BC4D5A2C274361517DE7C8E87E1AC0A66F3D99F593BE77F1B1343323C92F85B4801957E0F32CAB604252028ACB779E1DCA318A8A9F367F7BF9B4D7CDFEC06D878AF6D4EB4BD7F564BA7134479721CECA232CB0C0FD0F63C6FCC63EA393BA06E13FCF691FC40939B6B332842D8046EBC8049C0971FADACBBE3D28C80FB2F59FFCE1482D050FF3BDB22EF9E67295EB3C1F045EF3CB0F638CE5437E20F8126725E5DF1A867F59407795288B5E69385BDED43E1484886B08BCA06A84938F6BED0CF1326BA149FD3E45E533E3AC48E222025CBD27A33DD6A9BF46F35F601CE8E54DBD6E0ECECE1ECC8D6091F86836C781AC5D21E390FFF2CAAD3FA72497548365E77981C24707B3206E679035D668AE66245EA900FE533E8B935C84D5755ECA88AF396B52C7CBEDB448860D826DD0BEE671F07DE374AE31E71883AF95A45F38066C5BC78C49C783B85395A23627BF202397143F556DE4FB0C39977824834C4716C44435FC5B6286BC14E5D3DFE4C7133A88772509A54C80CCCE45433F7271E6434E37BB20754CA8C9462499BC4DA5E2010B06B05514F5FE7532E873D8918C594D28E2446D074B205589F1A50933EAE1165C48632CC110193D3CA6C6CE001E137A218AA9D09EA918881B5635BCADE6670CD061D7D9302561A5B7D4D752A67FAE30C30FD9D1C7CF83D7700ABD455CA2E190183361F9CF25D963E51CBC601E0FC9D752D45E0A72ACBDEE319927F72D023DB94BEB5DFF2153CC4D6187406A44FF8DEFD7045B3E5DF08A06851CF9B462804F339EB96F7D68BCEE2A3860E5DFD26C2884C121DCF3168185CB261FFE3C6F15343CC4769D0632214CC77EF6313D290D7F42CF317DD90FA6CC98983318863FB2A4C43E231F043CDEEF59C305F06B6AF08683B681CD6C7D7CB6B56EE778ED9FD2790C3D34C3754BD7E8A243D4813542E1DF34D127754F93A205F7889E14D9B21E1760318152E6E67FA608D1610CC1894A127595AF80A939A0FD1A18B5662F79AF3CB0EF0276767DFB062A1BD35CA95912F0B31D5951E0A4245856DDE9F11A782148ACC56F38D866B5505E5DBC2FA1204469AB5D44F996DFEE88F35E47ED8206EA5B537A77C175FAB0A392E6FA8C2BF69D63593D7F78CE72145228BD1CDC1ECC051869DF09CEC01DA31F997250D953745A28C61EB7EB379010518D83F8E1A27A81EA78C84DC7D12F64593D3051A5DA89CCF88580E4CE752F6A528041ADF62268F84F09A5CA7E66F6C4AA3E1FC481813C614BF4F783F5E9AC0846178DA1A7EB24BE1B0620826E34D4AC1C72F820DACBDA40294272093FCA2765DC7C052CCDA64A3C7998E0ADBD118FECC3260529D44D4B10BDA8CE9C9AAD5D15D799B0EB2B4976CBE99B78E4068C1105924D2CCC08FCE95B5963ABDF316D47417D7C73510450386565BDED107F4F278B6CA29D5109C5324CEEFA28A5B84F843932991DE2D1DF828916A097A53B233DF1B82DC084D624BF7F35BF0E2A551EFBCDD0A0B8324A68636B9B72BA68D1A1C6A89B7A736BC82381AE3CD6B4A5CCE0ED35C2B17ADD63BA8C908256AE5297AEC9D9ABD2EBE95A43617383F420AF893752B4B03463AAB3B88E3F835FD19504A615AFC739995D93960987235CA0FBAE7D9626045B2E6382521C4CF01C07AC26E9E1C5CFEAF782AD97E983F3A43F8E90314AC32C60D44AF7CBB1EC74C8BB5139526B2A577BCC2558503842F3AD9A2026D2ED104D462D035AB2CC3802D7136DFC938067F4EFD38ECFDBAE8FE30BC3342D3354628F0F87EDCD5F6A005F69A32A30DA6C6AC2188C3A11790867797D2D03D836B9F6FFD55C590F1AC8DF4A0F63B5201987C9AA05B4EAA91466E4D5454549E184306EB59381CAA20A3B1EFE7EFFC97A98A48E8712A0A98B4E39F050BFF5EFB72917E60DD1992DFC77840F00862FA81D34FBF774AB060B80E0805E63C65CE0B5651256D42A8376FD734BEECE02A58651CC8F567EAD91C0C60690D8C9104205A338B3DAB0F75221BE9AE505CFCB2343F9FD68CC79F96795C8ED06866B32CF12456C30232CDF5D1F8EB253777264EF7D3706E875DF54FC216B2DC90C6653D813E9135288730FC6A9178079D6E89694D9CC4CF828F06AE954224402B1FE2BBBA5A6DECA5344DD11DB77AE49D0BB3DA38FCACC15F8AD1BC5A6212F93F2AD285F5915A4AD642239CDB3240CD622E4DBEE18366BB2CB4604F92D8EFC693C3AB2F90AD84FCFD88CB461C3DF89043E94EFBF08FED2B98C5835CBFC3EDDBA653A33D35BA2E2D08F7ADA87A12FAF76DF84D170BD92A56E62DE8B8B0D1CCAEB4DB4BF7D2FA9F8F23A8443638D721BCCDD31D5396EE2BD5FB3F28BC877BF430908415DB46E3B93AF80016036B9CFA933486B83C19061387478808ABE63FDA4B0B76B3AD50343E540EC4F80400A362627273FC1EE643B6B7736B9338A7F1433780574224674D6F625BEAD125F3AD383EEAA12AFAF0DC812039741034A74423F57F82436542EE1FAA31EB72A98E8D060B992BD5954A42416C5C2A3C826D2F8743D9487DA95DF047B329E7FB125216FA1DE2577DA00998872C8B46FE665A20366EF8C839AA8F549C06917C2C752C72963FA1C619F0ADAB3E1309622E6B5EF01A31EB78380CBC657282604FA98AA9B51596F45B7CD3BEE7CD6E2AAC43224C052911EA564481B3FC4AE054BBF72666447110FA193CE8BB277F6D3D069A0BD7EE7D01075FA7E729F5F6E70E890287B52DC423180081FB7E267AC68EAB94786E73235530BB78A1C4AA5998529820572970063C09D1B15DBD2596D3BFD3DA6AA0CC600D9ADCE8D9EAAE3819B01F482BD852917CEB7C006E6E8FEB057EB0AC9A525A72EA433096C51C279506322F84D76E47612FE2BCD27849F6FE7CEC0DBEA27BEC270A696AB84DA1CCB190A97115447FDBF9362B23E89BCD9960A4436B8324903254E28344DB6376E25D2857CD37BAA99D656293E8F82D3A74DD4026D14B1F8935D581F973BBF5B75170E2655512C6CA0415193B75BE9EEB0F7F9884A7FF11BA473056D556FC7281A9DCD79B3F93515565A3079034C1C5C9DF838AD40897F37D74C090269914F89A60E3DB12CDB79E5CAE0F200310D0C1190047D314857DE44A62AFB1615CFBD25B93E2ADD774937660C9B8231D9D952E728CC0D67A74E76BEEE93189C9BA89EB55D933AD898C77ADF21C7DB40394525F0F3B1DDE711B54228DAA\""; +static int HexString2Hex(char *inHexString, char *outHex, int count) +{ + int ret = -1; + int len = 0; + int i; + char ch1, ch2; - FILE *pfd = popen(temp, "r"); - if (pfd == NULL) - perror("popen"); + if (NULL == inHexString) + return -1; - FILE *rfd = fopen("aixiao.rsa", "w+"); - fseek(rfd, 0, SEEK_SET); + len = count; - while (fgets(rsa, 512, pfd) != NULL) { - //printf("%s", rsa); - fwrite(rsa, strlen(rsa), 1, rfd); + if (len < 1) + return -1; + + len &= ~1; + for (i = 0; i < len; i += 2) { + ch1 = inHexString[i]; + ch2 = inHexString[i + 1]; + outHex[i / 2 + 1] = 0; + if (isxdigit(ch1) && isxdigit(ch2)) { + ch1 = oneHexChar2Hex(ch1); + ch2 = oneHexChar2Hex(ch2); + outHex[i / 2] = (ch1 << 4) | ch2; + } else { + goto EXIT; + } + } + return 0; +EXIT: + return ret; +} + +static int rsa_file() +{ + static uint8_t key[16] = "aixiao"; + + struct AES_ctx ctx; + AES_init_ctx(&ctx, key); + + static char temp[] = + "6681E82581AF0A621B2D5A82C161F7D053482050524956415445204B45592D2D2D2D2D0A6233426C626E4E7A614331725A586B74646A454141414141436D466C637A49314E69316A6448494141414147596D4E796558423041414141474141414142446C4664306F54620A71634F3837615369703756582B55414141414541414141414541414147584141414142334E7A614331796332454141414144415141424141414267514463596A734B346330770A757649304B4163454A385132717975592B57545149456B53446A672B5A67614A484B444166765678706C35313368535151654D7253754558725372526277504C6148417051490A7A79715273506F6C64553630454B4B335058374A483269544C5A70715A4F396645323965686B4F332B45675836714456553854755871377558356D326F75374B6F37385641440A42527A53743772647A4D6A304A762B4D61414C664C736F464A4E4462753457633171772B5A486E3566385253752F65423548664878545955764F33614A39717855626332496A0A5035466E43336B4C49487638467A375A30514D394935622F6D754631375156394379754D67756E517841546A4F6D4252736A46717036796E7374756F53526846524B302B67530A453234734D4A58392B6C684237714B6F44746E306B54474B545369646B7539696171585436306E52377445455A556B726A34453469304541305633736E326E7745447371796E0A76635563736F5868615159726A31532F4345487A6242525A6F51724532444C4450676D702B55714F315679754D72483153497568705633754345616444776265474E755978610A306478797A457446306B44774252654B3254467073312F746F776D2B754D5A4B444C7658586A375775702F394E4233447376544A365575343969717431746E73524C39354F4D0A72653630352F5331653575587341414157417377326A4E747645773975746C336741744F6A516D68596E6F684B4C765732695A5162625379564446556A6F2F39324E733735710A6D623971317933714661447270496E36596A39386E44516239346B2B4A624F6848422B6148554F5A6739683572392F5439422F672F72624F574A436336634A762F2B4A6656460A6345324B504F7A634E70392B334A5A4635654742706E49365A7470305A4B7364684545422B6D754C514E6B757A44426D48386F50536D57642F4F39586355325276596B45342F0A70537349744835475975747861414B444D543063692B6342745252615742626859676657416A50727439467A313063676E58327669674B73754E6C4F34696B7875514C6B49630A6C776D73414B2F36656774466C68654258747A6C657037787059744174516A317652594846644A2B5842325439532F616672636F626B306B70755552737361317350464274770A5979453459644B77557154484F4C4B6E45374A686D65306558715759336A7A6A5A6D775651757131354F6679666470482F737265566A656F644478616B584E74484C556770420A5647456147446F69494F70624F59382F6A34746C7862673164672F32503932663265744758634675434476586273507A30727054327054315230544F746B644D3132375059520A504542333155465172434545614A7A4E4434704B342F41797579707A4A652F486F596B4B784A5659546534654A6A4959746B53713777656137455A68724B2F4E7447617346350A4253566A4655766F774C33564D563633312F59586778757935584A4A3857504A684A7632375A64682F54514E426E6E78664369477764564D626A4A6E706251636F742F6F66730A70453833696451472B546273373064756F396A2F774C7162625050366453436C6A6E61304E77626132355659543152783968576531794955426F48463736344568763342786E0A6C353453764D63425A644C4C634F57504B464F3076544C6B394E41496969762F4C79506B3854625836507676477A52523447307245646365686E387352366B335A7530454F4E0A582B334451344A6F7968577477446C583878666A5732592F6B313546583871737534395431344B484A7A56736D4B6E622B714C514F4F305858464A5166376F4D427652464E4F0A325743484370445A4C394D31725966336D337245455335447879332F4D6553685353536E45634D5962572B32364842364570324E41714D71703351464A2F45506D54485054710A446A62652F496B48642B376D72326E4B5842456B2F47736C6371384B5963613565704C446A616E367939496538434D55534843637038526F446E78326258642B344E534977560A7047616F34784747644C2B53567953734453545776754D47715152545464334253315869794D6A3174566C782B6B4B674449724D51655971764D646573306F6E3451795062570A7A4A4B3639462F454B36633654442F4D5567777652656C6D6F2F586D6250694A6D376749643673432F5149674877774F334173533245593056786E6D58444B4C7877324B72730A3630663079786A2B344B7679552B79316C774F5257445542564C657A4E313062692F37395A7A2B366F2B523137735A7448307A34633371753238552F6C3179554E6D386A4F750A33492B6F7269785830464551574E34634B32543856785446304A5A78472B2B4F412B763438736E563268636638786F7652764B45422F764A6F464559617851684B56527538740A4779745A6D473079534F3461686D3968764D653162322B6A4454597A363034545234424C54422B35774A4F2B7A722B3362356134596C7653536E6D4448695831634E786E4A4A0A622F42716D55714F417A614A4D564C4C747553494C33503279554A56484B2B383675622F5431634E6C4F5442687950335075734E7A596A7647555735746B637451326F5170700A617853784B427976597A43586A4C3257324F6B6C4950765572327366446D335937457142656A6B6155746B6270346E467335646F4A51424E4E68344B6D797744767238722F6F0A79796146523544774C53636938423463636B684D534C66796E725A59646D2B4252486F4F676F3356665970304434326165494E5A645134584F397678774F7A4F5A6B566B6F360A334968684E4E2F5567584D536C484C4A357336567446486168774B5164796677466556574E337A4877302F457351477352646A612B3665794239564B7738794B5732765541520A6B6862325152753476635771384139762B447031515545755A486C462B6A65727365667A6B576636794246364B744E354A37566753664945644963526239766671514B2F686F0A58475A72574A346C6F41492B6B354D36385742524872546831656A785A4435336170366D43413836663249774F50724A7938616753504678355634654F7A586D3863443137790A414C4C6255503843706865454B43596946474F55365652334167444A7479436E674F624C6E4D4C7958442B494D47504E5964693161314644764B623958435277786833676A6F0A346D72664149386C76392B4B7872667844514C7359426D61715070514338545530785955714A4D372B4C34714A38376F79485166764C2B7A74655A2B61675433336F656D67670A704747565A513D3D0A2D2D2D2D2D454E44204F50454E5353482050524956415445204B45592D2D2D2D2D0A0A"; + uint8_t Hex_string[sizeof(temp) / 2]; + bzero(Hex_string, 0); + HexString2Hex((char *)temp, (char *)Hex_string, sizeof(temp)); + + AES_ECB_decrypt(&ctx, Hex_string); + //printf("%s\n", Hex_string); + + FILE *fp = fopen("aixiao.rsa", "w"); + if (fp == NULL) { + perror("fopen"); + return -1; } - fclose(pfd); - fclose(rfd); + fwrite(Hex_string, sizeof(Hex_string), 1, fp); + fclose(fp); return 0; } -void help_information() { +static void help_information() { puts("\n" "remote command\n" "Author: aixiao@aixiao.me\n" @@ -272,15 +325,15 @@ int main(int argc, char *argv[], char **env) { int rc; - int is=0; + int is = 0; int verbosity = SSH_LOG_PROTOCOL; ssh_session my_ssh_session; char host_ip[BUFFER_SIZE]; char password[BUFFER_SIZE]; char user[BUFFER_SIZE]; - char *priv_name = "aixiao.rsa"; // 私钥文件名称 - char priv_passwd[BUFFER_SIZE]; // 私钥的解密密钥 + char *priv_name = "aixiao.rsa"; // 私钥文件名称 + char priv_passwd[BUFFER_SIZE]; // 私钥的解密密钥 char command[BUFFER_SIZE]; int host_port = 22; @@ -290,7 +343,7 @@ int main(int argc, char *argv[], char **env) memset(priv_passwd, 0, BUFFER_SIZE); memset(command, 0, BUFFER_SIZE); - strcpy(user, "root"); + memcpy(user, "root", 4); int opt; char optstrs[] = "-:l:p:u:e:k:f:ic:h?"; @@ -334,8 +387,7 @@ int main(int argc, char *argv[], char **env) } my_ssh_session = ssh_new(); - if (my_ssh_session == NULL) - { + if (my_ssh_session == NULL) { exit(-1); } @@ -346,15 +398,13 @@ int main(int argc, char *argv[], char **env) rc = ssh_connect(my_ssh_session); // Verify the server's identity - if (verify_knownhost(my_ssh_session) < 0) - { + if (verify_knownhost(my_ssh_session) < 0) { ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); exit(-1); } - if (strlen(password) > 1) - { + if (strlen(password) > 1) { // Authenticate ourselves rc = ssh_userauth_password(my_ssh_session, user, password); if (rc != SSH_AUTH_SUCCESS) { @@ -363,9 +413,7 @@ int main(int argc, char *argv[], char **env) ssh_free(my_ssh_session); exit(-1); } - } - else - { + } else { // 私钥认证 authenticate_pubkey(my_ssh_session, priv_name, priv_passwd); } @@ -378,7 +426,7 @@ int main(int argc, char *argv[], char **env) // 释放已分配的SSH会话句柄 ssh_free(my_ssh_session); - system("test -f aixiao.rsa && rm aixiao.rsa"); + remove("aixiao.rsa"); return 0; } diff --git a/main.o b/main.o new file mode 100644 index 0000000000000000000000000000000000000000..d949f1862daf9b1983b5a3883955bfdf10087c4c GIT binary patch literal 48776 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 MC-WT3uyFhTZwvSv^#A|> literal 0 HcmV?d00001 diff --git a/remote_libssh b/remote_libssh new file mode 100644 index 0000000000000000000000000000000000000000..4be714e2888da8b6271a86e9676e32c4767b892c GIT binary patch literal 58792 zcmeFadwdkt{Wm_dv$NUUb`ugHAeRNg9YXe!O~OU9$!^#{AR!3|DlQ?}kVr^kcEjzf zf(Dd8qhQsdVzITgwrZu;TC3KgsGz-}trTm&6|I*|vC3Di;-%*IexI4yY^ZsDeLb(| z_5AU?7??Tde9q^5&gXv4%gB3&r4RXtUMl;|C?*YpaC5~)Z^$91YS zMY5o67BH>9L@Us%9VbnLOREl7P;y)jD_>KN(ZG^X8XU6ZxSD2S^~`B)oZZ^e*0p)| z<|6NGuO~0kp63!QkT1?bpIW$dxn$Zd9VW~e&pKU^YGwbwJ_`Nm=bzp9$mPW&@7i_g zt+&qotUF}T;27fYAimC0yj_eMafJNo*P>=t2%Cp!-ttKio6sr{Dc_ z7(hcF)tKPx5Z=V3Uk7�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 literal 0 HcmV?d00001