wirelessgateway/secure/SH_Secure.cpp

1436 lines
50 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include "SH_Secure.hpp"
#define AES_ENCRYPT 2
#define AES_DECRYPT 0
#define Length_(len) do{ \
len = ((((len>>3) + ((len&0x7)>0?1:0))<<4) + 8); \
} while (0)
namespace DEScrypt {
//u_char C[17][28], D[17][28], K[17][48];
int iip_tab_p[64] = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20,
12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53,
45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 };
int _iip_tab_p[64] = { 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23,
63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2,
42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 };
void Fexpand0(u_char *in, u_char *out) {
int divide;
int i, j;
for (i = 0; i < 8; i++) {
divide = 0x80;
for (j = 0; j < 8; j++) {
*out++ = (in[i] / divide) & 1;
divide /= 2;
}
}
}
void Fcompress0(u_char *out, u_char *in)
{
int times;
int i, j;
for (i = 0; i < 8; i++) {
times = 0x80;
in[i] = 0;
for (j = 0; j < 8; j++) {
in[i] += (*out++) * times;
times /= 2;
}
}
}
void Fcompress016(u_char *out, u_char *in)
{
int times;
int i, j;
for (i = 0; i < 16; i++) {
times = 0x8;
in[i] = '0';
for (j = 0; j < 4; j++) {
in[i] += (*out++) * times;
times /= 2;
}
}
}
int pc_1_cp[28] = { 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10,
2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36 };
int pc_1_dp[28] = { 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14,
6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 };
int pc_2p[48] = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4,
26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45,
33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 };
int ls_countp[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
void FLS(u_char *bits, u_char *buffer, int count)
{
for (int i = 0; i < 28; i++) {
buffer[i] = bits[(i + count) % 28];
}
}
void Fson(u_char *cc, u_char *dd, u_char *kk)
{
int i;
u_char buffer[56];
for (i = 0; i < 28; i++) {
buffer[i] = *cc++;
}
for (i = 28; i < 56; i++) {
buffer[i] = *dd++;
}
for (i = 0; i < 48; i++) {
*kk++ = buffer[pc_2p[i] - 1];
}
}
void Fsetkeystar(u_char bits[64], u_char K[17][48])
{
int i, j;
u_char C[17][28], D[17][28];
for (i = 0; i < 28; i++) {
C[0][i] = bits[pc_1_cp[i] - 1];
}
for (i = 0; i < 28; i++) {
D[0][i] = bits[pc_1_dp[i] - 1];
}
for (j = 0; j < 16; j++) {
FLS(C[j], C[j + 1], ls_countp[j]);
FLS(D[j], D[j + 1], ls_countp[j]);
Fson(C[j + 1], D[j + 1], K[j + 1]);
}
}
void Fiip(u_char *text, u_char *ll, u_char *rr)
{
u_char buffer[64];
Fexpand0(text, buffer);
int i;
for (i = 0; i < 32; i++) {
ll[i] = buffer[iip_tab_p[i] - 1];
}
for (i = 0; i < 32; i++) {
rr[i] = buffer[iip_tab_p[i + 32] - 1];
}
}
void _Fiip(u_char *text, u_char *ll, u_char *rr)
{
u_char tmp[64];
int i;
for (i = 0; i < 32; i++) {
tmp[i] = ll[i];
}
for (i = 32; i < 64; i++) {
tmp[i] = rr[i - 32];
}
for (i = 0; i < 64; i++) {
text[i] = tmp[_iip_tab_p[i] - 1];
}
}
int e_r_p[48] = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 };
int local_PP[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31,
10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 };
int ccom_SSS_p[8][4][16] = { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0,
7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,/* err on */
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 15, 12, 8, 2, 4,
9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15,
2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0, 14, 7, 11, 10, 4, 13, 1, 5, 8,
12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14,
9,
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3,
4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 13, 6, 4, 9, 8, 15, 3, 0, 11, 1,
2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2,
12,
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6,
15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 10, 6, 9, 0, 12, 11, 7, 13, 15, 1,
3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2,
14, /* err on */
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4,
7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, /* err on */
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1,
14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7,
12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 9, 14, 15, 5, 2, 8, 12, 3, 7, 0,
4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8,
13,
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4,
9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10,
15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3,
12,
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10,
3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6,
10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6,
11 };
void Fs_box(u_char *aa, u_char *bb)
{
int i, j, k, m;
int y, z;
u_char ss[8];
m = 0;
for (i = 0; i < 8; i++) {
j = 6 * i;
y = aa[j] * 2 + aa[j + 5];
z = aa[j + 1] * 8 + aa[j + 2] * 4 + aa[j + 3] * 2 + aa[j + 4];
ss[i] = ccom_SSS_p[i][y][z];
y = 0x08;
for (k = 0; k < 4; k++) {
bb[m++] = (ss[i] / y) & 1;
y /= 2;
}
}
}
void FF(int n, u_char *ll, u_char *rr, u_char *LL, u_char *RR,u_char K[17][48])
{
int i;
u_char buffer[64], tmp[64];
for (i = 0; i < 48; i++) {
buffer[i] = rr[e_r_p[i] - 1];
}
for (i = 0; i < 48; i++) {
buffer[i] = (buffer[i] + K[n][i]) & 1;
}
Fs_box(buffer, tmp);
for (i = 0; i < 32; i++) {
buffer[i] = tmp[local_PP[i] - 1];
}
for (i = 0; i < 32; i++) {
RR[i] = (buffer[i] + ll[i]) & 1;
}
for (i = 0; i < 32; i++) {
LL[i] = rr[i];
}
}
void Fencrypt0(u_char *text, u_char *mtext, u_char k[17][48])
{
u_char ll[64], rr[64], LL[64], RR[64];
u_char tmp[64];
int i, j;
Fiip(text, ll, rr);
for (i = 1; i < 17; i++) {
FF(i, ll, rr, LL, RR,k);
for (j = 0; j < 32; j++) {
ll[j] = LL[j];
rr[j] = RR[j];
}
}
_Fiip(tmp, rr, ll);
Fcompress0(tmp, mtext);
}
void Fdiscrypt0(u_char *mtext, u_char *text, u_char k[17][48])
{
u_char ll[64], rr[64], LL[64], RR[64];
u_char tmp[64];
int i, j;
Fiip(mtext, ll, rr);
for (i = 16; i > 0; i--) {
FF(i, ll, rr, LL, RR,k);
for (j = 0; j < 32; j++) {
ll[j] = LL[j];
rr[j] = RR[j];
}
}
_Fiip(tmp, rr, ll);
Fcompress0(tmp, text);
}
void FDES(u_char *key, u_char *text, u_char *mtext, u_char k[17][48])
{
u_char tmp[64];
Fexpand0(key, tmp);
Fsetkeystar(tmp,k);
Fencrypt0(text, mtext,k);
}
void _FDES(u_char *key, u_char *mtext, u_char *text,u_char k[17][48])
{
u_char tmp[64];
Fexpand0(key, tmp);
Fsetkeystar(tmp,k);
Fdiscrypt0(mtext, text,k);
}
}
namespace TEAcrypt {
const u_char TEA_key[16] = { 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05,
0x09, 0x09, 0x0A, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C };
#define MX (z>>5^y<<2)+(y>>3^z<<4)^(sum^y)+(k[p&3^e]^z)
#define DELTA 0x9e3779b9
#define S_LOOPTIME 1 //5
#define BLOCK_SIZE 31 //PAGE_SIZE,根据你所要加密的数据包长度修改此参数(单位:字节)
void btea_encrypt(u_char* buf, u_char len)
{
u_char n = len >> 2;
u_long *v = (u_long *) buf;
u_long *k = (u_long *) TEA_key;
u_long z = v[n - 1], y = v[0], sum = 0, e;
u_char p, q;
// Coding Part
if (n == 0) {
return;
}
q = S_LOOPTIME + 52 / n;
while (q-- > 0) {
sum += DELTA;
e = sum >> 2 & 3;
for (p = 0; p < n - 1; p++)
y = v[p + 1], z = v[p] += MX;
y = v[0];
z = v[n - 1] += MX;
}
}
void btea_decrpyt(u_char* buf, u_char len)
{
u_char n = len >> 2;
u_long *v = (u_long *) buf;
u_long *k = (u_long *) TEA_key;
u_long z = v[n - 1], y = v[0], sum = 0, e;
u_char p, q;
//Decoding Part...
if (n == 0) {
return;
}
q = S_LOOPTIME + 52 / n;
sum = q * DELTA;
while (sum != 0) {
e = sum >> 2 & 3;
for (p = n - 1; p > 0; p--)
z = v[p - 1], y = v[p] -= MX;
z = v[n - 1];
y = v[0] -= MX;
sum -= DELTA;
}
}
}
namespace MD5crypt {
typedef struct {
u_long i[2]; /* number of _bits_ handled mod 2^64 */
u_long buf[4]; /* scratch buffer */
unsigned char in[64]; /* input buffer */
unsigned char digest[16]; /* actual digest after MD5Final call */
} MD5_CTX;
unsigned char PADDING[64] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* F, G and H are basic MD5 functions: selection, majority, parity */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
/* Rotation is separate from addition to prevent recomputation */
#define FF(a, b, c, d, x, s, ac) \
{(a) += F ((b), (c), (d)) + (x) + (u_long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) \
{(a) += G ((b), (c), (d)) + (x) + (u_long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) \
{(a) += H ((b), (c), (d)) + (x) + (u_long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) \
{(a) += I ((b), (c), (d)) + (x) + (u_long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* Basic MD5 step. Transform buf based on in.
*/
void Transform(u_long *buf, u_long *in) {
u_long a = buf[0], b = buf[1], c = buf[2], d = buf[3];
/* Round 1 */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
FF ( a, b, c, d, in[ 0], S11, 3614090360UL); /* 1 */
FF ( d, a, b, c, in[ 1], S12, 3905402710UL); /* 2 */
FF ( c, d, a, b, in[ 2], S13, 606105819UL); /* 3 */
FF ( b, c, d, a, in[ 3], S14, 3250441966UL); /* 4 */
FF ( a, b, c, d, in[ 4], S11, 4118548399UL); /* 5 */
FF ( d, a, b, c, in[ 5], S12, 1200080426UL); /* 6 */
FF ( c, d, a, b, in[ 6], S13, 2821735955UL); /* 7 */
FF ( b, c, d, a, in[ 7], S14, 4249261313UL); /* 8 */
FF ( a, b, c, d, in[ 8], S11, 1770035416UL); /* 9 */
FF ( d, a, b, c, in[ 9], S12, 2336552879UL); /* 10 */
FF ( c, d, a, b, in[10], S13, 4294925233UL); /* 11 */
FF ( b, c, d, a, in[11], S14, 2304563134UL); /* 12 */
FF ( a, b, c, d, in[12], S11, 1804603682UL); /* 13 */
FF ( d, a, b, c, in[13], S12, 4254626195UL); /* 14 */
FF ( c, d, a, b, in[14], S13, 2792965006UL); /* 15 */
FF ( b, c, d, a, in[15], S14, 1236535329UL); /* 16 */
/* Round 2 */
#define S21 5
#define S22 9
#define S23 14
#define S24 20
GG ( a, b, c, d, in[ 1], S21, 4129170786UL); /* 17 */
GG ( d, a, b, c, in[ 6], S22, 3225465664UL); /* 18 */
GG ( c, d, a, b, in[11], S23, 643717713UL); /* 19 */
GG ( b, c, d, a, in[ 0], S24, 3921069994UL); /* 20 */
GG ( a, b, c, d, in[ 5], S21, 3593408605UL); /* 21 */
GG ( d, a, b, c, in[10], S22, 38016083UL); /* 22 */
GG ( c, d, a, b, in[15], S23, 3634488961UL); /* 23 */
GG ( b, c, d, a, in[ 4], S24, 3889429448UL); /* 24 */
GG ( a, b, c, d, in[ 9], S21, 568446438UL); /* 25 */
GG ( d, a, b, c, in[14], S22, 3275163606UL); /* 26 */
GG ( c, d, a, b, in[ 3], S23, 4107603335UL); /* 27 */
GG ( b, c, d, a, in[ 8], S24, 1163531501UL); /* 28 */
GG ( a, b, c, d, in[13], S21, 2850285829UL); /* 29 */
GG ( d, a, b, c, in[ 2], S22, 4243563512UL); /* 30 */
GG ( c, d, a, b, in[ 7], S23, 1735328473UL); /* 31 */
GG ( b, c, d, a, in[12], S24, 2368359562UL); /* 32 */
/* Round 3 */
#define S31 4
#define S32 11
#define S33 16
#define S34 23
HH ( a, b, c, d, in[ 5], S31, 4294588738UL); /* 33 */
HH ( d, a, b, c, in[ 8], S32, 2272392833UL); /* 34 */
HH ( c, d, a, b, in[11], S33, 1839030562UL); /* 35 */
HH ( b, c, d, a, in[14], S34, 4259657740UL); /* 36 */
HH ( a, b, c, d, in[ 1], S31, 2763975236UL); /* 37 */
HH ( d, a, b, c, in[ 4], S32, 1272893353UL); /* 38 */
HH ( c, d, a, b, in[ 7], S33, 4139469664UL); /* 39 */
HH ( b, c, d, a, in[10], S34, 3200236656UL); /* 40 */
HH ( a, b, c, d, in[13], S31, 681279174UL); /* 41 */
HH ( d, a, b, c, in[ 0], S32, 3936430074UL); /* 42 */
HH ( c, d, a, b, in[ 3], S33, 3572445317UL); /* 43 */
HH ( b, c, d, a, in[ 6], S34, 76029189UL); /* 44 */
HH ( a, b, c, d, in[ 9], S31, 3654602809UL); /* 45 */
HH ( d, a, b, c, in[12], S32, 3873151461UL); /* 46 */
HH ( c, d, a, b, in[15], S33, 530742520UL); /* 47 */
HH ( b, c, d, a, in[ 2], S34, 3299628645UL); /* 48 */
/* Round 4 */
#define S41 6
#define S42 10
#define S43 15
#define S44 21
II ( a, b, c, d, in[ 0], S41, 4096336452UL); /* 49 */
II ( d, a, b, c, in[ 7], S42, 1126891415UL); /* 50 */
II ( c, d, a, b, in[14], S43, 2878612391UL); /* 51 */
II ( b, c, d, a, in[ 5], S44, 4237533241UL); /* 52 */
II ( a, b, c, d, in[12], S41, 1700485571UL); /* 53 */
II ( d, a, b, c, in[ 3], S42, 2399980690UL); /* 54 */
II ( c, d, a, b, in[10], S43, 4293915773UL); /* 55 */
II ( b, c, d, a, in[ 1], S44, 2240044497UL); /* 56 */
II ( a, b, c, d, in[ 8], S41, 1873313359UL); /* 57 */
II ( d, a, b, c, in[15], S42, 4264355552UL); /* 58 */
II ( c, d, a, b, in[ 6], S43, 2734768916UL); /* 59 */
II ( b, c, d, a, in[13], S44, 1309151649UL); /* 60 */
II ( a, b, c, d, in[ 4], S41, 4149444226UL); /* 61 */
II ( d, a, b, c, in[11], S42, 3174756917UL); /* 62 */
II ( c, d, a, b, in[ 2], S43, 718787259UL); /* 63 */
II ( b, c, d, a, in[ 9], S44, 3951481745UL); /* 64 */
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
void MD5Init(MD5_CTX *mdContext)
{
mdContext->i[0] = mdContext->i[1] = (u_long) 0;
/* Load magic initialization constants.
*/
mdContext->buf[0] = (u_long) 0x67452301;
mdContext->buf[1] = (u_long) 0xefcdab89;
mdContext->buf[2] = (u_long) 0x98badcfe;
mdContext->buf[3] = (u_long) 0x10325476;
}
void MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
{
u_long in[16];
int mdi;
unsigned int i, ii;
/* compute number of bytes mod 64 */
mdi = (int) ((mdContext->i[0] >> 3) & 0x3F);
/* update number of bits */
if ((mdContext->i[0] + ((u_long) inLen << 3)) < mdContext->i[0])
mdContext->i[1]++;
mdContext->i[0] += ((u_long) inLen << 3);
mdContext->i[1] += ((u_long) inLen >> 29);
while (inLen--) {
/* add new character to buffer, increment mdi */
mdContext->in[mdi++] = *inBuf++;
/* transform if necessary */
if (mdi == 0x40) {
for (i = 0, ii = 0; i < 16; i++, ii += 4)
in[i] = (((u_long) mdContext->in[ii + 3]) << 24)
| (((u_long) mdContext->in[ii + 2]) << 16)
| (((u_long) mdContext->in[ii + 1]) << 8)
| ((u_long) mdContext->in[ii]);
Transform(mdContext->buf, in);
mdi = 0;
}
}
}
void MD5Final(MD5_CTX *mdContext)
{
u_long in[16];
int mdi;
unsigned int i, ii;
unsigned int padLen;
/* save number of bits */
in[14] = mdContext->i[0];
in[15] = mdContext->i[1];
/* compute number of bytes mod 64 */
mdi = (int) ((mdContext->i[0] >> 3) & 0x3F);
/* pad out to 56 mod 64 */
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
MD5Update(mdContext, PADDING, padLen);
/* append length in bits and transform */
for (i = 0, ii = 0; i < 14; i++, ii += 4)
in[i] = (((u_long) mdContext->in[ii + 3]) << 24)
| (((u_long) mdContext->in[ii + 2]) << 16)
| (((u_long) mdContext->in[ii + 1]) << 8)
| ((u_long) mdContext->in[ii]);
Transform(mdContext->buf, in);
/* store buffer in digest */
for (i = 0, ii = 0; i < 4; i++, ii += 4) {
mdContext->digest[ii] = (unsigned char) (mdContext->buf[i] & 0xFF);
mdContext->digest[ii + 1] = (unsigned char) ((mdContext->buf[i] >> 8)
& 0xFF);
mdContext->digest[ii + 2] = (unsigned char) ((mdContext->buf[i] >> 16)
& 0xFF);
mdContext->digest[ii + 3] = (unsigned char) ((mdContext->buf[i] >> 24)
& 0xFF);
}
}
}
namespace AEScrypt {
/*
* Forward S-box
*/
static const unsigned char FSb[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
};
/*
* Forward tables
*/
#define FT \
\
V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
#define V(a,b,c,d) 0x##a##b##c##d
static const unsigned int FT0[256] = { FT };
#undef V
#define V(a,b,c,d) 0x##b##c##d##a
static const unsigned int FT1[256] = { FT };
#undef V
#define V(a,b,c,d) 0x##c##d##a##b
static const unsigned int FT2[256] = { FT };
#undef V
#define V(a,b,c,d) 0x##d##a##b##c
static const unsigned int FT3[256] = { FT };
#undef V
#undef FT
/*
* Reverse S-box
*/
static const unsigned char RSb[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
};
/*
* Reverse tables
*/
#define RT \
\
V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
#define V(a,b,c,d) 0x##a##b##c##d
static const unsigned int RT0[256] = { RT };
#undef V
#define V(a,b,c,d) 0x##b##c##d##a
static const unsigned int RT1[256] = { RT };
#undef V
#define V(a,b,c,d) 0x##c##d##a##b
static const unsigned int RT2[256] = { RT };
#undef V
#define V(a,b,c,d) 0x##d##a##b##c
static const unsigned int RT3[256] = { RT };
#undef V
#undef RT
/*
* Round constants
*/
static const unsigned int RCON[10] =
{
0x00000001, 0x00000002, 0x00000004, 0x00000008,
0x00000010, 0x00000020, 0x00000040, 0x00000080,
0x0000001B, 0x00000036
};
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
{ \
X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \
FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y3 >> 24 ) & 0xFF ]; \
\
X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \
FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y0 >> 24 ) & 0xFF ]; \
\
X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \
FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y1 >> 24 ) & 0xFF ]; \
\
X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \
FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y2 >> 24 ) & 0xFF ]; \
}
#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
{ \
X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \
RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
RT3[ ( Y1 >> 24 ) & 0xFF ]; \
\
X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \
RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
RT3[ ( Y2 >> 24 ) & 0xFF ]; \
\
X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \
RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
RT3[ ( Y3 >> 24 ) & 0xFF ]; \
\
X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \
RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
RT3[ ( Y0 >> 24 ) & 0xFF ]; \
}
void aes_crypt_ecb_update(Secure::aes_context* ctx, int mode, const unsigned char input[16], unsigned char output[16])
{
int i;
unsigned int* RK;
unsigned int X[4], Y[4];
RK = ctx->rk;
for (i = 0; i < 4; i++)
{
X[i] = (*((unsigned int*)input + i)) ^ (*RK++);
}
if (mode == AES_DECRYPT)
{
for (i = (ctx->nr >> 1) - 1; i > 0; i--)
{
AES_RROUND(Y[0], Y[1], Y[2], Y[3], X[0], X[1], X[2], X[3]);
AES_RROUND(X[0], X[1], X[2], X[3], Y[0], Y[1], Y[2], Y[3]);
}
AES_RROUND(Y[0], Y[1], Y[2], Y[3], X[0], X[1], X[2], X[3]);
X[0] = *RK++ ^ \
((unsigned int)RSb[(Y[0]) & 0xFF]) ^
((unsigned int)RSb[(Y[3] >> 8) & 0xFF] << 8) ^
((unsigned int)RSb[(Y[2] >> 16) & 0xFF] << 16) ^
((unsigned int)RSb[(Y[1] >> 24) & 0xFF] << 24);
X[1] = *RK++ ^ \
((unsigned int)RSb[(Y[1]) & 0xFF]) ^
((unsigned int)RSb[(Y[0] >> 8) & 0xFF] << 8) ^
((unsigned int)RSb[(Y[3] >> 16) & 0xFF] << 16) ^
((unsigned int)RSb[(Y[2] >> 24) & 0xFF] << 24);
X[2] = *RK++ ^ \
((unsigned int)RSb[(Y[2]) & 0xFF]) ^
((unsigned int)RSb[(Y[1] >> 8) & 0xFF] << 8) ^
((unsigned int)RSb[(Y[0] >> 16) & 0xFF] << 16) ^
((unsigned int)RSb[(Y[3] >> 24) & 0xFF] << 24);
X[3] = *RK++ ^ \
((unsigned int)RSb[(Y[3]) & 0xFF]) ^
((unsigned int)RSb[(Y[2] >> 8) & 0xFF] << 8) ^
((unsigned int)RSb[(Y[1] >> 16) & 0xFF] << 16) ^
((unsigned int)RSb[(Y[0] >> 24) & 0xFF] << 24);
}
else /* AES_ENCRYPT */
{
for (i = (ctx->nr >> 1) - 1; i > 0; i--)
{
AES_FROUND(Y[0], Y[1], Y[2], Y[3], X[0], X[1], X[2], X[3]);
AES_FROUND(X[0], X[1], X[2], X[3], Y[0], Y[1], Y[2], Y[3]);
}
AES_FROUND(Y[0], Y[1], Y[2], Y[3], X[0], X[1], X[2], X[3]);
X[0] = *RK++ ^ \
((unsigned int)FSb[(Y[0]) & 0xFF]) ^
((unsigned int)FSb[(Y[1] >> 8) & 0xFF] << 8) ^
((unsigned int)FSb[(Y[2] >> 16) & 0xFF] << 16) ^
((unsigned int)FSb[(Y[3] >> 24) & 0xFF] << 24);
X[1] = *RK++ ^ \
((unsigned int)FSb[(Y[1]) & 0xFF]) ^
((unsigned int)FSb[(Y[2] >> 8) & 0xFF] << 8) ^
((unsigned int)FSb[(Y[3] >> 16) & 0xFF] << 16) ^
((unsigned int)FSb[(Y[0] >> 24) & 0xFF] << 24);
X[2] = *RK++ ^ \
((unsigned int)FSb[(Y[2]) & 0xFF]) ^
((unsigned int)FSb[(Y[3] >> 8) & 0xFF] << 8) ^
((unsigned int)FSb[(Y[0] >> 16) & 0xFF] << 16) ^
((unsigned int)FSb[(Y[1] >> 24) & 0xFF] << 24);
X[3] = *RK++ ^ \
((unsigned int)FSb[(Y[3]) & 0xFF]) ^
((unsigned int)FSb[(Y[0] >> 8) & 0xFF] << 8) ^
((unsigned int)FSb[(Y[1] >> 16) & 0xFF] << 16) ^
((unsigned int)FSb[(Y[2] >> 24) & 0xFF] << 24);
}
memcpy(output, X, 16);
}
}
Secure::Secure()
{
memset(KEY,0,KEYLen);
memset(result,0,sizeof(result));
}
Secure::~Secure()
{
}
void Secure::GetKey(std::string gwmac)
{
std::string keyStr = FnMD5CACL((unsigned char*)(gwmac.c_str()), gwmac.length());
keyStr= keyStr.substr(0, 8);
strcpy(KEY, keyStr.c_str());
}
void Secure::GetKey(char *pKey,std::string pImeiId)
{
std::string keyStr = FnMD5CACL((unsigned char *) (pImeiId.c_str()),
pImeiId.length());
keyStr = keyStr.substr(0, 8);
strcpy(pKey, keyStr.c_str());
}
char * Secure::Base64Encode(const unsigned char * bindata, char * base64, int binlength)
{
int i, j;
unsigned char current;
const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (i = 0, j = 0; i < binlength; i += 3)
{
current = (bindata[i] >> 2);
current &= (unsigned char)0x3F;
base64[j++] = base64char[(int)current];
current = ((unsigned char)(bindata[i] << 4)) & ((unsigned char)0x30);
if (i + 1 >= binlength)
{
base64[j++] = base64char[(int)current];
base64[j++] = '=';
base64[j++] = '=';
break;
}
current |= ((unsigned char)(bindata[i + 1] >> 4)) & ((unsigned char)0x0F);
base64[j++] = base64char[(int)current];
current = ((unsigned char)(bindata[i + 1] << 2)) & ((unsigned char)0x3C);
if (i + 2 >= binlength)
{
base64[j++] = base64char[(int)current];
base64[j++] = '=';
break;
}
current |= ((unsigned char)(bindata[i + 2] >> 6)) & ((unsigned char)0x03);
base64[j++] = base64char[(int)current];
current = ((unsigned char)bindata[i + 2]) & ((unsigned char)0x3F);
base64[j++] = base64char[(int)current];
}
base64[j] = '\0';
return base64;
}
int Secure::Base64Decode( const char * base64, unsigned char * bindata)
{
int i, j;
unsigned char k;
unsigned char temp[4];
const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 )
{
memset( temp, 0xFF, sizeof(temp) );
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i] )
temp[0]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+1] )
temp[1]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+2] )
temp[2]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+3] )
temp[3]= k;
}
bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) |
((unsigned char)((unsigned char)(temp[1]>>4)&0x03));
if ( base64[i+2] == '=' )
break;
bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) |
((unsigned char)((unsigned char)(temp[2]>>2)&0x0F));
if ( base64[i+3] == '=' )
break;
bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) |
((unsigned char)(temp[3]&0x3F));
}
return j;
}
int Secure::ZigbeeDataEncrypt(char *pData)//zigbee数据加密
{
assert(pData!=NULL);
int dataLen = strlen(pData);
if (dataLen > 9) {
if (strstr(pData, "\r\n")) {
dataLen = dataLen - 2;
}
BteaEncrypt((unsigned char *)pData,dataLen);
return dataLen + 2;
}
return dataLen;
}
int Secure::ZigbeeDataEncrypt_Hex(char *pData, int len)//zigbee数据加密, 限制长度,包含\r\n
{
assert(pData!=NULL);
int dataLen = len;
if (dataLen > 9) {
dataLen = dataLen - 2; //除去\r\n长度
BteaEncrypt((unsigned char *)pData,dataLen);
return dataLen + 2;
}
return dataLen;
}
void Secure::ZigbeeDataDecrypt(char *pData,int pLen)//zigbee数据解密
{
assert(pData!=NULL);
//if (pLen > 9) {
BteaDecrpyt((u_char *)pData, pLen - 2);
//}
}
/*
* pMing : 明文
* pMi : 密文
* pKey : key
*/
int Secure::NetDataEncrypt(char* pMing, char* pMi, char* pKey)//网络数据加密
{
int i = 0;
int lenMing = strlen(pMing);
if (strlen(pKey) == 0) {
#ifdef _SOFTWARE_DEBUG_
strncpy(pMi,pMing,lenMing);
strcat(pMi, "\r\n");
Length_(lenMing);
return lenMing;
#else
return 0;
#endif
}
int lenMi = lenMing;
char *ming = new char[lenMing + 8];//明文长度,长度不对加密错误
memset(ming, 0, lenMing + 8);
strncpy(ming,pMing,lenMing);
Length_(lenMi);
char *miTmp = new char[lenMi];//存储密文
memset(miTmp,0,lenMi);
lenMing = Encrypt((u_char*)ming, (u_char *) miTmp,lenMing,
(u_char *) pKey);
while (i < lenMing)
{
sprintf(&pMi[i*2], "%02X", miTmp[i]&0x00FF);
i++;
}
if (!strstr(pMi, "\r\n")) {
strcat(pMi, "\r\n");
}
delete[] ming;
delete[] miTmp;
return strlen(pMi);
}
int Secure::NetDataDecrypt(char* pMing, char* pMi,int pLen,char* pKey)//网络数据解密
{
//if ((pMi==NULL)||(pKey==NULL))
// return -1;
int j, k,buf_len;
buf_len = pLen+1;
char *buff = new char[buf_len]; //中间数据
memset(buff, 0, buf_len);
char temp[4] = { 0 };
//密文每2个字节数据(前一字节作为高4 位后一字节作为低4 位),
//合为1字节数据然后进行解密如"C1" = C*16+1=109
for (j = 0, k = 0; j < buf_len && k < buf_len; j += 2, k++) {
strncpy(temp, &pMi[j], 2);
unsigned char ss = strtol(temp, NULL, 16);
buff[k] = ss;
}
Decrypt((u_char *) pMing, (u_char *) buff, k-1, (u_char *) pKey);
delete[] buff;
return k-1;
}
int Secure::NetDataDecrypt(char* pMing, char* pMi,char* pKey)//网络数据解密
{
if ((pMi==NULL)||(pKey==NULL))
return -1;
int j, k,buf_len;
std::string mi(pMi);
buf_len = strlen(pMi) + 1;
char *buff = new char[buf_len]; //中间数据
memset(buff, 0, buf_len);
char temp[4] = { 0 };
//密文每2个字节数据(前一字节作为高4 位后一字节作为低4 位),
//合为1字节数据然后进行解密如"C1" = C*16+1=109
for (j = 0, k = 0; j < buf_len && k < buf_len; j += 2, k++) {
strncpy(temp, mi.substr(j, 2).c_str(), sizeof temp);
unsigned char ss = strtol(temp, NULL, 16);
buff[k] = ss;
}
Decrypt((u_char *) pMing, (u_char *) buff, k-1, (u_char *) pKey);
delete [] buff;
return k-1;
}
void Secure::aes_setkey_enc(aes_context* ctx, const unsigned char* key, int keysize)
{
int i;
unsigned int* RK;
switch (keysize)
{
case 128:
ctx->nr = 10;
break;
case 192:
ctx->nr = 12;
break;
case 256:
ctx->nr = 14;
break;
default:
keysize = 128;
ctx->nr = 10;
break;
}
ctx->rk = RK = ctx->buf;
memcpy(RK, key, keysize >> 3);
switch (ctx->nr)
{
case 10:
for (i = 0; i < 10; i++, RK += 4)
{
RK[4] = RK[0] ^ AEScrypt::RCON[i] ^
((unsigned int)AEScrypt::FSb[(RK[3] >> 8) & 0xFF]) ^
((unsigned int)AEScrypt::FSb[(RK[3] >> 16) & 0xFF] << 8) ^
((unsigned int)AEScrypt::FSb[(RK[3] >> 24) & 0xFF] << 16) ^
((unsigned int)AEScrypt::FSb[(RK[3]) & 0xFF] << 24);
RK[5] = RK[1] ^ RK[4];
RK[6] = RK[2] ^ RK[5];
RK[7] = RK[3] ^ RK[6];
}
break;
case 12:
for (i = 0; i < 8; i++, RK += 6)
{
RK[6] = RK[0] ^ AEScrypt::RCON[i] ^
((unsigned int)AEScrypt::FSb[(RK[5] >> 8) & 0xFF]) ^
((unsigned int)AEScrypt::FSb[(RK[5] >> 16) & 0xFF] << 8) ^
((unsigned int)AEScrypt::FSb[(RK[5] >> 24) & 0xFF] << 16) ^
((unsigned int)AEScrypt::FSb[(RK[5]) & 0xFF] << 24);
RK[7] = RK[1] ^ RK[6];
RK[8] = RK[2] ^ RK[7];
RK[9] = RK[3] ^ RK[8];
RK[10] = RK[4] ^ RK[9];
RK[11] = RK[5] ^ RK[10];
}
break;
case 14:
for (i = 0; i < 7; i++, RK += 8)
{
RK[8] = RK[0] ^ AEScrypt::RCON[i] ^
((unsigned int)AEScrypt::FSb[(RK[7] >> 8) & 0xFF]) ^
((unsigned int)AEScrypt::FSb[(RK[7] >> 16) & 0xFF] << 8) ^
((unsigned int)AEScrypt::FSb[(RK[7] >> 24) & 0xFF] << 16) ^
((unsigned int)AEScrypt::FSb[(RK[7]) & 0xFF] << 24);
RK[9] = RK[1] ^ RK[8];
RK[10] = RK[2] ^ RK[9];
RK[11] = RK[3] ^ RK[10];
RK[12] = RK[4] ^
((unsigned int)AEScrypt::FSb[(RK[11]) & 0xFF]) ^
((unsigned int)AEScrypt::FSb[(RK[11] >> 8) & 0xFF] << 8) ^
((unsigned int)AEScrypt::FSb[(RK[11] >> 16) & 0xFF] << 16) ^
((unsigned int)AEScrypt::FSb[(RK[11] >> 24) & 0xFF] << 24);
RK[13] = RK[5] ^ RK[12];
RK[14] = RK[6] ^ RK[13];
RK[15] = RK[7] ^ RK[14];
}
break;
}
}
void Secure::aes_setkey_dec(aes_context* ctx, const unsigned char* key, int keysize)
{
int i, j;
aes_context cty;
unsigned int* RK;
unsigned int* SK;
ctx->rk = RK = ctx->buf;
aes_setkey_enc(&cty, key, keysize);
ctx->nr = cty.nr;
SK = cty.rk + (cty.nr << 2);
memcpy(RK, SK, sizeof(unsigned int) << 2);
RK += 4;
SK -= 4;
for (i = ctx->nr - 1; i > 0; i--, SK -= 8)
{
for (j = 0; j < 4; j++, SK++)
{
*RK++ = AEScrypt::RT0[AEScrypt::FSb[(*SK) & 0xFF]] ^
AEScrypt::RT1[AEScrypt::FSb[(*SK >> 8) & 0xFF]] ^
AEScrypt::RT2[AEScrypt::FSb[(*SK >> 16) & 0xFF]] ^
AEScrypt::RT3[AEScrypt::FSb[(*SK >> 24) & 0xFF]];
}
}
memcpy(RK, SK, sizeof(unsigned int) << 2);
}
// free later
unsigned char* Secure::aes_crypt_ecb(aes_context* ctx, int mode, const unsigned char* input, int slen, int* dlen)
{
register int i;
register int n;
unsigned char* output;
unsigned char buff[16];
if (mode == AES_ENCRYPT)
{
n = 16 - (slen & 15);
*dlen = slen + n;
output = (unsigned char*)malloc(*dlen);
if (!output)
{
return NULL;
}
memset(output, 0, *dlen);
memset(buff, n, sizeof(buff));
if (slen & 15)
{
memcpy(buff, input + (slen & ~15), slen & 15);
}
n = (slen >> 4);
for (i = 0; i < n; i++)
{
AEScrypt::aes_crypt_ecb_update(ctx, AES_ENCRYPT, \
input + (i << 4), output + (i << 4));
}
AEScrypt::aes_crypt_ecb_update(ctx, AES_ENCRYPT, buff, output + (i << 4));
}
else
{
output = (unsigned char*)malloc(slen);
if (!output)
{
return NULL;
}
memset(output, 0, *dlen);
n = (slen >> 4);
for (i = 0; i < n; i++)
{
AEScrypt::aes_crypt_ecb_update(ctx, AES_DECRYPT, \
input + (i << 4), output + (i << 4));
}
*dlen = slen - (int)output[slen - 1];
}
return output;
}
int Secure::Encrypt(u_char *plaintext, u_char *ciphertext, int p_len, u_char *key)
{
int i;
u_char K[17][48];
for (i = 0; i < p_len; i += 8) {
DEScrypt::FDES(key, plaintext + i, ciphertext + i,K);
}
return i;
}
int Secure::Decrypt(u_char *plaintext, u_char *ciphertext, int p_len, u_char *key)
{
int i;
u_char K[17][48];
for (i = 0; i < p_len; i += 8) {
DEScrypt::_FDES(key, ciphertext + i, plaintext + i,K);
}
return i;
}
void Secure::BteaEncrypt(u_char* buf, u_char len)
{
TEAcrypt::btea_encrypt(buf, len);
}
void Secure::BteaDecrpyt(u_char* buf, u_char len)
{
TEAcrypt::btea_decrpyt(buf, len);
}
char* Secure::FnMD5CACL(u_char *buf, int len)
{
memset(result, 0, sizeof result);
MD5crypt::MD5_CTX p_ctx;
MD5crypt::MD5Init(&p_ctx);
MD5crypt::MD5Update(&p_ctx, buf, len);
MD5crypt::MD5Final(&p_ctx);
for (int i = 0; i < 16; i++) {
sprintf(&result[i * 2], "%02x", p_ctx.digest[i]);
}
return result;
}
char* Secure::Md5Sum(const char* filename)
{
unsigned char data_buf[1024];
unsigned char md5[16];
MD5crypt::MD5_CTX ctx;
int data_fd;
int nread;
int i;
data_fd = open(filename, O_RDONLY);
if (data_fd == -1)
{
printf("open file error\n");
}
MD5crypt::MD5Init(&ctx);
while (nread = read(data_fd, data_buf, sizeof(data_buf)), nread > 0)
{
MD5crypt::MD5Update(&ctx, data_buf, nread);
}
MD5crypt::MD5Final(&ctx);
memset(result, 0, sizeof result);
for (i = 0; i < 16; ++i)
{
sprintf(&result[i * 2], "%02x", ctx.digest[i]);
}
return result;
}