mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-12 01:53:07 +03:00
adding authentication, AES alignment issue, MACRO issue
git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@59 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
139
ssl/aes.c
139
ssl/aes.c
@ -62,10 +62,6 @@
|
||||
(f8)^=rot2(f4), \
|
||||
(f8)^rot1(f9))
|
||||
|
||||
/* some macros to do endian independent byte extraction */
|
||||
#define n2l(c,l) l=ntohl(*c); c++
|
||||
#define l2n(l,c) *c++=htonl(l)
|
||||
|
||||
/*
|
||||
* AES S-box
|
||||
*/
|
||||
@ -249,7 +245,7 @@ void AES_convert_key(AES_CTX *ctx)
|
||||
k = ctx->ks;
|
||||
k += 4;
|
||||
|
||||
for (i=ctx->rounds*4; i>4; i--)
|
||||
for (i= ctx->rounds*4; i > 4; i--)
|
||||
{
|
||||
w= *k;
|
||||
w = inv_mix_col(w,t1,t2,t3,t4);
|
||||
@ -262,46 +258,38 @@ void AES_convert_key(AES_CTX *ctx)
|
||||
*/
|
||||
void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
|
||||
{
|
||||
uint32_t tin0, tin1, tin2, tin3;
|
||||
uint32_t tout0, tout1, tout2, tout3;
|
||||
uint32_t tin[4];
|
||||
uint32_t *iv = (uint32_t *)ctx->iv;
|
||||
uint32_t *msg_32 = (uint32_t *)msg;
|
||||
uint32_t *out_32 = (uint32_t *)out;
|
||||
int i;
|
||||
uint32_t tin[4], tout[4], iv[4];
|
||||
|
||||
n2l(iv, tout0);
|
||||
n2l(iv, tout1);
|
||||
n2l(iv, tout2);
|
||||
n2l(iv, tout3);
|
||||
iv -= 4;
|
||||
memcpy(iv, ctx->iv, AES_IV_SIZE);
|
||||
for (i = 0; i < 4; i++)
|
||||
tout[i] = ntohl(iv[i]);
|
||||
|
||||
for (length -= 16; length >= 0; length -= 16)
|
||||
for (length -= AES_BLOCKSIZE; length >= 0; length -= AES_BLOCKSIZE)
|
||||
{
|
||||
n2l(msg_32, tin0);
|
||||
n2l(msg_32, tin1);
|
||||
n2l(msg_32, tin2);
|
||||
n2l(msg_32, tin3);
|
||||
tin[0] = tin0^tout0;
|
||||
tin[1] = tin1^tout1;
|
||||
tin[2] = tin2^tout2;
|
||||
tin[3] = tin3^tout3;
|
||||
uint32_t msg_32[4];
|
||||
uint32_t out_32[4];
|
||||
memcpy(msg_32, msg, AES_BLOCKSIZE);
|
||||
msg += AES_BLOCKSIZE;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
tin[i] = ntohl(msg_32[i])^tout[i];
|
||||
|
||||
AES_encrypt(ctx, tin);
|
||||
|
||||
tout0 = tin[0];
|
||||
l2n(tout0, out_32);
|
||||
tout1 = tin[1];
|
||||
l2n(tout1, out_32);
|
||||
tout2 = tin[2];
|
||||
l2n(tout2, out_32);
|
||||
tout3 = tin[3];
|
||||
l2n(tout3, out_32);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
tout[i] = tin[i];
|
||||
out_32[i] = htonl(tout[i]);
|
||||
}
|
||||
|
||||
memcpy(out, out_32, AES_BLOCKSIZE);
|
||||
out += AES_BLOCKSIZE;
|
||||
}
|
||||
|
||||
l2n(tout0, iv);
|
||||
l2n(tout1, iv);
|
||||
l2n(tout2, iv);
|
||||
l2n(tout3, iv);
|
||||
for (i = 0; i < 4; i++)
|
||||
iv[i] = htonl(tout[i]);
|
||||
memcpy(ctx->iv, iv, AES_IV_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -309,54 +297,42 @@ void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
|
||||
*/
|
||||
void AES_cbc_decrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
|
||||
{
|
||||
uint32_t tin0, tin1, tin2, tin3;
|
||||
uint32_t xor0,xor1,xor2,xor3;
|
||||
uint32_t tout0,tout1,tout2,tout3;
|
||||
uint32_t data[4];
|
||||
uint32_t *iv = (uint32_t *)ctx->iv;
|
||||
uint32_t *msg_32 = (uint32_t *)msg;
|
||||
uint32_t *out_32 = (uint32_t *)out;
|
||||
int i;
|
||||
uint32_t tin[4], xor[4], tout[4], data[4], iv[4];
|
||||
|
||||
n2l(iv ,xor0);
|
||||
n2l(iv, xor1);
|
||||
n2l(iv, xor2);
|
||||
n2l(iv, xor3);
|
||||
iv -= 4;
|
||||
memcpy(iv, ctx->iv, AES_IV_SIZE);
|
||||
for (i = 0; i < 4; i++)
|
||||
xor[i] = ntohl(iv[i]);
|
||||
|
||||
for (length-=16; length >= 0; length -= 16)
|
||||
for (length -= 16; length >= 0; length -= 16)
|
||||
{
|
||||
n2l(msg_32, tin0);
|
||||
n2l(msg_32, tin1);
|
||||
n2l(msg_32, tin2);
|
||||
n2l(msg_32, tin3);
|
||||
uint32_t msg_32[4];
|
||||
uint32_t out_32[4];
|
||||
memcpy(msg_32, msg, AES_BLOCKSIZE);
|
||||
msg += AES_BLOCKSIZE;
|
||||
|
||||
data[0] = tin0;
|
||||
data[1] = tin1;
|
||||
data[2] = tin2;
|
||||
data[3] = tin3;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
tin[i] = ntohl(msg_32[i]);
|
||||
data[i] = tin[i];
|
||||
}
|
||||
|
||||
AES_decrypt(ctx, data);
|
||||
|
||||
tout0 = data[0]^xor0;
|
||||
tout1 = data[1]^xor1;
|
||||
tout2 = data[2]^xor2;
|
||||
tout3 = data[3]^xor3;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
tout[i] = data[i]^xor[i];
|
||||
xor[i] = tin[i];
|
||||
out_32[i] = htonl(tout[i]);
|
||||
}
|
||||
|
||||
xor0 = tin0;
|
||||
xor1 = tin1;
|
||||
xor2 = tin2;
|
||||
xor3 = tin3;
|
||||
|
||||
l2n(tout0, out_32);
|
||||
l2n(tout1, out_32);
|
||||
l2n(tout2, out_32);
|
||||
l2n(tout3, out_32);
|
||||
memcpy(out, out_32, AES_BLOCKSIZE);
|
||||
out += AES_BLOCKSIZE;
|
||||
}
|
||||
|
||||
l2n(xor0, iv);
|
||||
l2n(xor1, iv);
|
||||
l2n(xor2, iv);
|
||||
l2n(xor3, iv);
|
||||
for (i = 0; i < 4; i++)
|
||||
iv[i] = htonl(xor[i]);
|
||||
memcpy(ctx->iv, iv, AES_IV_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -375,9 +351,7 @@ static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
|
||||
/* Pre-round key addition */
|
||||
for (row = 0; row < 4; row++)
|
||||
{
|
||||
data[row] ^= *(k++);
|
||||
}
|
||||
|
||||
/* Encrypt one block. */
|
||||
for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
|
||||
@ -395,7 +369,6 @@ static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
{
|
||||
tmp1 = a0 ^ a1 ^ a2 ^ a3;
|
||||
old_a0 = a0;
|
||||
|
||||
a0 ^= tmp1 ^ AES_xtime(a0 ^ a1);
|
||||
a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);
|
||||
a2 ^= tmp1 ^ AES_xtime(a2 ^ a3);
|
||||
@ -408,9 +381,7 @@ static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
/* KeyAddition - note that it is vital that this loop is separate from
|
||||
the MixColumn operation, which must be atomic...*/
|
||||
for (row = 0; row < 4; row++)
|
||||
{
|
||||
data[row] = tmp[row] ^ *(k++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -424,16 +395,14 @@ static void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
uint32_t a0, a1, a2, a3, row;
|
||||
int curr_rnd;
|
||||
int rounds = ctx->rounds;
|
||||
uint32_t *k = (uint32_t*)ctx->ks + ((rounds+1)*4);
|
||||
const uint32_t *k = ctx->ks + ((rounds+1)*4);
|
||||
|
||||
/* pre-round key addition */
|
||||
for (row=4; row > 0;row--)
|
||||
{
|
||||
data[row-1] ^= *(--k);
|
||||
}
|
||||
|
||||
/* Decrypt one block */
|
||||
for (curr_rnd=0; curr_rnd < rounds; curr_rnd++)
|
||||
for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
|
||||
{
|
||||
/* Perform ByteSub and ShiftRow operations together */
|
||||
for (row = 4; row > 0; row--)
|
||||
@ -468,9 +437,7 @@ static void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
}
|
||||
|
||||
for (row = 4; row > 0; row--)
|
||||
{
|
||||
data[row-1] = tmp[row-1] ^ *(--k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
13
ssl/crypto.h
13
ssl/crypto.h
@ -34,13 +34,15 @@ extern "C" {
|
||||
**************************************************************************/
|
||||
|
||||
#define AES_MAXROUNDS 14
|
||||
#define AES_BLOCKSIZE 16
|
||||
#define AES_IV_SIZE 16
|
||||
|
||||
typedef struct aes_key_st
|
||||
{
|
||||
uint16_t rounds;
|
||||
uint16_t key_size;
|
||||
uint32_t ks[(AES_MAXROUNDS+1)*8];
|
||||
uint8_t iv[16];
|
||||
uint8_t iv[AES_IV_SIZE];
|
||||
} AES_CTX;
|
||||
|
||||
typedef enum
|
||||
@ -106,9 +108,9 @@ typedef struct
|
||||
uint8_t buffer[64]; /* input buffer */
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5Init(MD5_CTX *);
|
||||
void MD5Update(MD5_CTX *, const uint8_t *msg, int len);
|
||||
void MD5Final(MD5_CTX *, uint8_t *digest);
|
||||
EXP_FUNC void STDCALL MD5Init(MD5_CTX *);
|
||||
EXP_FUNC void STDCALL MD5Update(MD5_CTX *, const uint8_t *msg, int len);
|
||||
EXP_FUNC void STDCALL MD5Final(MD5_CTX *, uint8_t *digest);
|
||||
|
||||
/**************************************************************************
|
||||
* HMAC declarations
|
||||
@ -273,6 +275,9 @@ void print_blob(const char *format, const uint8_t *data, int size, ...);
|
||||
#define print_blob(...)
|
||||
#endif
|
||||
|
||||
EXP_FUNC int STDCALL base64_decode(const char *in, int len,
|
||||
uint8_t *out, int *outlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -267,3 +267,78 @@ void print_blob(const char *format,
|
||||
void print_blob(const char *format, const unsigned char *data,
|
||||
int size, ...) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SSL_HAS_PEM) || defined(CONFIG_HTTP_HAS_AUTHORIZATION)
|
||||
/* base64 to binary lookup table */
|
||||
static const uint8_t map[128] =
|
||||
{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
|
||||
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
|
||||
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 255, 255, 255, 255, 255
|
||||
};
|
||||
|
||||
EXP_FUNC int STDCALL base64_decode(const char *in, int len,
|
||||
uint8_t *out, int *outlen)
|
||||
{
|
||||
int g, t, x, y, z;
|
||||
uint8_t c;
|
||||
int ret = -1;
|
||||
|
||||
g = 3;
|
||||
for (x = y = z = t = 0; x < len; x++)
|
||||
{
|
||||
if ((c = map[in[x]&0x7F]) == 0xff)
|
||||
continue;
|
||||
|
||||
if (c == 254) /* this is the end... */
|
||||
{
|
||||
c = 0;
|
||||
|
||||
if (--g < 0)
|
||||
goto error;
|
||||
}
|
||||
else if (g != 3) /* only allow = at end */
|
||||
goto error;
|
||||
|
||||
t = (t<<6) | c;
|
||||
|
||||
if (++y == 4)
|
||||
{
|
||||
out[z++] = (uint8_t)((t>>16)&255);
|
||||
|
||||
if (g > 1)
|
||||
out[z++] = (uint8_t)((t>>8)&255);
|
||||
|
||||
if (g > 2)
|
||||
out[z++] = (uint8_t)(t&255);
|
||||
|
||||
y = t = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (y != 0)
|
||||
goto error;
|
||||
|
||||
if (outlen)
|
||||
*outlen = z;
|
||||
ret = 0;
|
||||
|
||||
error:
|
||||
#ifdef CONFIG_SSL_FULL_MODE
|
||||
if (ret < 0)
|
||||
printf("Error: Invalid base64\n"); TTY_FLUSH();
|
||||
#endif
|
||||
TTY_FLUSH();
|
||||
return ret;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
71
ssl/loader.c
71
ssl/loader.c
@ -169,22 +169,6 @@ void ssl_obj_free(SSLObjLoader *ssl_obj)
|
||||
#define IS_ENCRYPTED_PRIVATE_KEY 1
|
||||
#define IS_CERTIFICATE 2
|
||||
|
||||
/* base64 to binary lookup table */
|
||||
static const uint8_t map[128] =
|
||||
{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
|
||||
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
|
||||
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 255, 255, 255, 255, 255
|
||||
};
|
||||
|
||||
static const char * const begins[NUM_PEM_TYPES] =
|
||||
{
|
||||
"-----BEGIN RSA PRIVATE KEY-----",
|
||||
@ -205,59 +189,6 @@ static const char * const aes_str[2] =
|
||||
"DEK-Info: AES-256-CBC,"
|
||||
};
|
||||
|
||||
static int base64_decode(const uint8_t *in, int len,
|
||||
uint8_t *out, int *outlen)
|
||||
{
|
||||
int g, t, x, y, z;
|
||||
uint8_t c;
|
||||
int ret = -1;
|
||||
|
||||
g = 3;
|
||||
for (x = y = z = t = 0; x < len; x++)
|
||||
{
|
||||
if ((c = map[in[x] & 0x7F]) == 0xff)
|
||||
continue;
|
||||
|
||||
if (c == 254) /* this is the end... */
|
||||
{
|
||||
c = 0;
|
||||
|
||||
if (--g < 0)
|
||||
goto error;
|
||||
}
|
||||
else if (g != 3) /* only allow = at end */
|
||||
goto error;
|
||||
|
||||
t = (t<<6) | c;
|
||||
|
||||
if (++y == 4)
|
||||
{
|
||||
out[z++] = (uint8_t)((t>>16)&255);
|
||||
|
||||
if (g > 1)
|
||||
out[z++] = (uint8_t)((t>>8)&255);
|
||||
|
||||
if (g > 2)
|
||||
out[z++] = (uint8_t)(t&255);
|
||||
|
||||
y = t = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (y != 0)
|
||||
goto error;
|
||||
|
||||
*outlen = z;
|
||||
ret = 0;
|
||||
|
||||
error:
|
||||
#ifdef CONFIG_SSL_FULL_MODE
|
||||
if (ret < 0)
|
||||
printf("Error: Invalid base64 file\n");
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a base64 blob of data and decrypt it (using AES) into its
|
||||
* proper ASN.1 form.
|
||||
@ -372,7 +303,7 @@ static int new_pem_obj(SSLCTX *ssl_ctx, int is_cacert, uint8_t *where,
|
||||
strstr((const char *)start, "4,ENCRYPTED"))
|
||||
{
|
||||
/* check for encrypted PEM file */
|
||||
if ((pem_size = pem_decrypt(start, end, password, ssl_obj)) < 0)
|
||||
if (pem_decrypt(start, end, password, ssl_obj) < 0)
|
||||
goto error;
|
||||
}
|
||||
else if (base64_decode(start, pem_size,
|
||||
|
@ -90,7 +90,7 @@ static const uint8_t PADDING[64] =
|
||||
/**
|
||||
* MD5 initialization - begins an MD5 operation, writing a new ctx.
|
||||
*/
|
||||
void MD5Init(MD5_CTX *ctx)
|
||||
EXP_FUNC void STDCALL MD5Init(MD5_CTX *ctx)
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
|
||||
@ -105,7 +105,7 @@ void MD5Init(MD5_CTX *ctx)
|
||||
/**
|
||||
* Accepts an array of octets as the next portion of the message.
|
||||
*/
|
||||
void MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
|
||||
EXP_FUNC void STDCALL MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
|
||||
{
|
||||
uint32_t x;
|
||||
int i, partLen;
|
||||
@ -141,7 +141,7 @@ void MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
|
||||
/**
|
||||
* Return the 128-bit message digest into the user's array
|
||||
*/
|
||||
void MD5Final(MD5_CTX *ctx, uint8_t *digest)
|
||||
EXP_FUNC void STDCALL MD5Final(MD5_CTX *ctx, uint8_t *digest)
|
||||
{
|
||||
uint8_t bits[8];
|
||||
uint32_t x, padLen;
|
||||
|
@ -29,7 +29,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(CYGWIN)
|
||||
#if defined(WIN32) || defined(CONFIG_PLATFORM_CYGWIN)
|
||||
#define STDCALL __stdcall
|
||||
#define EXP_FUNC __declspec(dllexport)
|
||||
#else
|
||||
@ -56,6 +56,7 @@ extern "C" {
|
||||
#endif /* _WIN32_WCE */
|
||||
|
||||
#include <winsock.h>
|
||||
#include <direct.h>
|
||||
#undef getpid
|
||||
#undef open
|
||||
#undef close
|
||||
@ -81,6 +82,7 @@ extern "C" {
|
||||
#define usleep(A) Sleep(A/1000)
|
||||
#define lseek(A,B,C) _lseek(A,B,C)
|
||||
#define strdup(A) _strdup(A)
|
||||
#define chroot(A) _chdir(A)
|
||||
|
||||
/* This fix gets around a problem where a win32 application on a cygwin xterm
|
||||
doesn't display regular output (until a certain buffer limit) - but it works
|
||||
@ -113,7 +115,7 @@ extern EXP_FUNC int strcasecmp(const char *s1, const char *s2);
|
||||
|
||||
#else /* Not Win32 */
|
||||
|
||||
#ifdef SOLARIS
|
||||
#ifdef CONFIG_PLATFORM_SOLARIS
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
|
@ -1123,6 +1123,7 @@ static void set_key_block(SSL *ssl, int is_write)
|
||||
/* clean up if possible */
|
||||
if (key_block_existed)
|
||||
{
|
||||
memset(ssl->key_block, 0, ciph_info->key_block_size);
|
||||
free(ssl->key_block);
|
||||
ssl->key_block = NULL;
|
||||
}
|
||||
@ -1454,9 +1455,11 @@ int process_finished(SSL *ssl, int hs_len)
|
||||
ssl->all_pkts = NULL;
|
||||
ssl->all_pkts_len = 0;
|
||||
|
||||
memset(ssl->master_secret, 0, SSL_SECRET_SIZE);
|
||||
free(ssl->master_secret);
|
||||
ssl->master_secret = NULL;
|
||||
|
||||
memset(ssl->final_finish_mac, 0, SSL_FINISHED_HASH_SIZE);
|
||||
free(ssl->final_finish_mac);
|
||||
ssl->final_finish_mac = NULL;
|
||||
|
||||
|
Reference in New Issue
Block a user