forked from wolfSSL/wolfssl
Merge branch 'master' of github.com:cyassl/cyassl
This commit is contained in:
9
README
9
README
@ -37,10 +37,19 @@ before calling SSL_new(); Though it's not recommended.
|
|||||||
|
|
||||||
CyaSSL Release 2.9.0 (X/XX/XXXX)
|
CyaSSL Release 2.9.0 (X/XX/XXXX)
|
||||||
|
|
||||||
|
Release 2.9.0 CyaSSL has bug fixes and new features including:
|
||||||
|
- Freescale Kinetis RNGB support
|
||||||
|
- Freescale Kinetis mmCAU support
|
||||||
|
|
||||||
The Freescale Kinetis K53 RNGB documentation can be found in Chapter 33 of the
|
The Freescale Kinetis K53 RNGB documentation can be found in Chapter 33 of the
|
||||||
K53 Sub-Family Reference Manual:
|
K53 Sub-Family Reference Manual:
|
||||||
http://cache.freescale.com/files/32bit/doc/ref_manual/K53P144M100SF2RM.pdf
|
http://cache.freescale.com/files/32bit/doc/ref_manual/K53P144M100SF2RM.pdf
|
||||||
|
|
||||||
|
Freescale Kinetis K60 mmCAU (AES, DES, 3DES, MD5, SHA, SHA256) documentation
|
||||||
|
can be found in the "ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library
|
||||||
|
User Guide":
|
||||||
|
http://cache.freescale.com/files/32bit/doc/user_guide/CAUAPIUG.pdf
|
||||||
|
|
||||||
|
|
||||||
*****************CyaSSL Release 2.8.0 (8/30/2013)
|
*****************CyaSSL Release 2.8.0 (8/30/2013)
|
||||||
|
|
||||||
|
@ -62,8 +62,8 @@
|
|||||||
* document (See note in README).
|
* document (See note in README).
|
||||||
*/
|
*/
|
||||||
#include "stm32f2xx.h"
|
#include "stm32f2xx.h"
|
||||||
#include "stm32f2xx_cryp.h"
|
#include "stm32f2xx_cryp.h"
|
||||||
|
|
||||||
int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
|
int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
|
||||||
int dir)
|
int dir)
|
||||||
{
|
{
|
||||||
@ -553,6 +553,93 @@ int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined FREESCALE_MMCAU
|
||||||
|
/*
|
||||||
|
* Freescale mmCAU hardware AES support through the CAU/mmCAU library.
|
||||||
|
* Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU
|
||||||
|
* Software Library User Guide (See note in README).
|
||||||
|
*/
|
||||||
|
#include "cau_api.h"
|
||||||
|
|
||||||
|
int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
|
||||||
|
int dir)
|
||||||
|
{
|
||||||
|
byte *rk = (byte*)aes->key;
|
||||||
|
|
||||||
|
if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
aes->rounds = keylen/4 + 6;
|
||||||
|
cau_aes_set_key(userKey, keylen*8, rk);
|
||||||
|
|
||||||
|
return AesSetIV(aes, iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int offset = 0;
|
||||||
|
int len = sz;
|
||||||
|
|
||||||
|
byte *iv, *enc_key;
|
||||||
|
byte temp_block[AES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
iv = (byte*)aes->reg;
|
||||||
|
enc_key = (byte*)aes->key;
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
/* XOR block with IV for CBC */
|
||||||
|
for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||||
|
temp_block[i] ^= iv[i];
|
||||||
|
|
||||||
|
cau_aes_encrypt(temp_block, enc_key, aes->rounds, out + offset);
|
||||||
|
|
||||||
|
len -= AES_BLOCK_SIZE;
|
||||||
|
offset += AES_BLOCK_SIZE;
|
||||||
|
|
||||||
|
/* store IV for next block */
|
||||||
|
XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int offset = 0;
|
||||||
|
int len = sz;
|
||||||
|
|
||||||
|
byte* iv, *dec_key;
|
||||||
|
byte temp_block[AES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
iv = (byte*)aes->reg;
|
||||||
|
dec_key = (byte*)aes->key;
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
cau_aes_decrypt(in + offset, dec_key, aes->rounds, out + offset);
|
||||||
|
|
||||||
|
/* XOR block with IV for CBC */
|
||||||
|
for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||||
|
(out + offset)[i] ^= iv[i];
|
||||||
|
|
||||||
|
/* store IV for next block */
|
||||||
|
XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
len -= AES_BLOCK_SIZE;
|
||||||
|
offset += AES_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else /* CTaoCrypt software implementation */
|
#else /* CTaoCrypt software implementation */
|
||||||
|
|
||||||
static const word32 rcon[] = {
|
static const word32 rcon[] = {
|
||||||
|
@ -413,6 +413,187 @@ void Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined FREESCALE_MMCAU
|
||||||
|
/*
|
||||||
|
* Freescale mmCAU hardware DES/3DES support through the CAU/mmCAU library.
|
||||||
|
* Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU
|
||||||
|
* Software Library User Guide (See note in README).
|
||||||
|
*/
|
||||||
|
#include "cau_api.h"
|
||||||
|
|
||||||
|
const unsigned char parityLookup[128] =
|
||||||
|
{
|
||||||
|
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
|
||||||
|
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
|
||||||
|
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
|
||||||
|
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
|
||||||
|
};
|
||||||
|
|
||||||
|
void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
byte* dkey = (byte*)des->key;
|
||||||
|
|
||||||
|
XMEMCPY(dkey, key, 8);
|
||||||
|
|
||||||
|
Des_SetIV(des, iv);
|
||||||
|
|
||||||
|
/* fix key parity, if needed */
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
dkey[i] = ((dkey[i] & 0xFE) | parityLookup[dkey[i] >> 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
byte* dkey1 = (byte*)des->key[0];
|
||||||
|
byte* dkey2 = (byte*)des->key[1];
|
||||||
|
byte* dkey3 = (byte*)des->key[2];
|
||||||
|
|
||||||
|
XMEMCPY(dkey1, key, 8); /* set key 1 */
|
||||||
|
XMEMCPY(dkey2, key + 8, 8); /* set key 2 */
|
||||||
|
XMEMCPY(dkey3, key + 16, 8); /* set key 3 */
|
||||||
|
|
||||||
|
Des3_SetIV(des, iv);
|
||||||
|
|
||||||
|
/* fix key parity if needed */
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
dkey1[i] = ((dkey1[i] & 0xFE) | parityLookup[dkey1[i] >> 1]);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
dkey2[i] = ((dkey2[i] & 0xFE) | parityLookup[dkey2[i] >> 1]);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
dkey3[i] = ((dkey3[i] & 0xFE) | parityLookup[dkey3[i] >> 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int offset = 0;
|
||||||
|
int len = sz;
|
||||||
|
byte *iv;
|
||||||
|
byte temp_block[DES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
iv = (byte*)des->reg;
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
/* XOR block with IV for CBC */
|
||||||
|
for (i = 0; i < DES_BLOCK_SIZE; i++)
|
||||||
|
temp_block[i] ^= iv[i];
|
||||||
|
|
||||||
|
cau_des_encrypt(temp_block, (byte*)des->key, out + offset);
|
||||||
|
|
||||||
|
len -= DES_BLOCK_SIZE;
|
||||||
|
offset += DES_BLOCK_SIZE;
|
||||||
|
|
||||||
|
/* store IV for next block */
|
||||||
|
XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int offset = 0;
|
||||||
|
int len = sz;
|
||||||
|
byte* iv;
|
||||||
|
byte temp_block[DES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
iv = (byte*)des->reg;
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
cau_des_decrypt(in + offset, (byte*)des->key, out + offset);
|
||||||
|
|
||||||
|
/* XOR block with IV for CBC */
|
||||||
|
for (i = 0; i < DES_BLOCK_SIZE; i++)
|
||||||
|
(out + offset)[i] ^= iv[i];
|
||||||
|
|
||||||
|
/* store IV for next block */
|
||||||
|
XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
len -= DES_BLOCK_SIZE;
|
||||||
|
offset += DES_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int offset = 0;
|
||||||
|
int len = sz;
|
||||||
|
|
||||||
|
byte *iv;
|
||||||
|
byte temp_block[DES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
iv = (byte*)des->reg;
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
/* XOR block with IV for CBC */
|
||||||
|
for (i = 0; i < DES_BLOCK_SIZE; i++)
|
||||||
|
temp_block[i] ^= iv[i];
|
||||||
|
|
||||||
|
cau_des_encrypt(temp_block , (byte*)des->key[0], out + offset);
|
||||||
|
cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset);
|
||||||
|
cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset);
|
||||||
|
|
||||||
|
len -= DES_BLOCK_SIZE;
|
||||||
|
offset += DES_BLOCK_SIZE;
|
||||||
|
|
||||||
|
/* store IV for next block */
|
||||||
|
XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int offset = 0;
|
||||||
|
int len = sz;
|
||||||
|
|
||||||
|
byte* iv;
|
||||||
|
byte temp_block[DES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
iv = (byte*)des->reg;
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
cau_des_decrypt(in + offset , (byte*)des->key[2], out + offset);
|
||||||
|
cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset);
|
||||||
|
cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset);
|
||||||
|
|
||||||
|
/* XOR block with IV for CBC */
|
||||||
|
for (i = 0; i < DES_BLOCK_SIZE; i++)
|
||||||
|
(out + offset)[i] ^= iv[i];
|
||||||
|
|
||||||
|
/* store IV for next block */
|
||||||
|
XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
len -= DES_BLOCK_SIZE;
|
||||||
|
offset += DES_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#else /* CTaoCrypt software implementation */
|
#else /* CTaoCrypt software implementation */
|
||||||
|
|
||||||
/* permuted choice table (key) */
|
/* permuted choice table (key) */
|
||||||
|
@ -36,6 +36,13 @@
|
|||||||
#include <ctaocrypt/src/misc.c>
|
#include <ctaocrypt/src/misc.c>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FREESCALE_MMCAU
|
||||||
|
#include "cau_api.h"
|
||||||
|
#define XTRANSFORM(S,B) cau_md5_hash_n((B), 1, (unsigned char*)(S)->digest)
|
||||||
|
#else
|
||||||
|
#define XTRANSFORM(S,B) Transform((S))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef STM32F2_HASH
|
#ifdef STM32F2_HASH
|
||||||
/*
|
/*
|
||||||
@ -174,6 +181,7 @@ void InitMd5(Md5* md5)
|
|||||||
md5->hiLen = 0;
|
md5->hiLen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef FREESCALE_MMCAU
|
||||||
|
|
||||||
static void Transform(Md5* md5)
|
static void Transform(Md5* md5)
|
||||||
{
|
{
|
||||||
@ -266,6 +274,8 @@ static void Transform(Md5* md5)
|
|||||||
md5->digest[3] += d;
|
md5->digest[3] += d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* FREESCALE_MMCAU */
|
||||||
|
|
||||||
|
|
||||||
static INLINE void AddLength(Md5* md5, word32 len)
|
static INLINE void AddLength(Md5* md5, word32 len)
|
||||||
{
|
{
|
||||||
@ -289,10 +299,10 @@ void Md5Update(Md5* md5, const byte* data, word32 len)
|
|||||||
len -= add;
|
len -= add;
|
||||||
|
|
||||||
if (md5->buffLen == MD5_BLOCK_SIZE) {
|
if (md5->buffLen == MD5_BLOCK_SIZE) {
|
||||||
#ifdef BIG_ENDIAN_ORDER
|
#if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||||
ByteReverseBytes(local, local, MD5_BLOCK_SIZE);
|
ByteReverseBytes(local, local, MD5_BLOCK_SIZE);
|
||||||
#endif
|
#endif
|
||||||
Transform(md5);
|
XTRANSFORM(md5, local);
|
||||||
AddLength(md5, MD5_BLOCK_SIZE);
|
AddLength(md5, MD5_BLOCK_SIZE);
|
||||||
md5->buffLen = 0;
|
md5->buffLen = 0;
|
||||||
}
|
}
|
||||||
@ -304,7 +314,7 @@ void Md5Final(Md5* md5, byte* hash)
|
|||||||
{
|
{
|
||||||
byte* local = (byte*)md5->buffer;
|
byte* local = (byte*)md5->buffer;
|
||||||
|
|
||||||
AddLength(md5, md5->buffLen); /* before adding pads */
|
AddLength(md5, md5->buffLen); /* before adding pads */
|
||||||
|
|
||||||
local[md5->buffLen++] = 0x80; /* add 1 */
|
local[md5->buffLen++] = 0x80; /* add 1 */
|
||||||
|
|
||||||
@ -313,10 +323,10 @@ void Md5Final(Md5* md5, byte* hash)
|
|||||||
XMEMSET(&local[md5->buffLen], 0, MD5_BLOCK_SIZE - md5->buffLen);
|
XMEMSET(&local[md5->buffLen], 0, MD5_BLOCK_SIZE - md5->buffLen);
|
||||||
md5->buffLen += MD5_BLOCK_SIZE - md5->buffLen;
|
md5->buffLen += MD5_BLOCK_SIZE - md5->buffLen;
|
||||||
|
|
||||||
#ifdef BIG_ENDIAN_ORDER
|
#if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||||
ByteReverseBytes(local, local, MD5_BLOCK_SIZE);
|
ByteReverseBytes(local, local, MD5_BLOCK_SIZE);
|
||||||
#endif
|
#endif
|
||||||
Transform(md5);
|
XTRANSFORM(md5, local);
|
||||||
md5->buffLen = 0;
|
md5->buffLen = 0;
|
||||||
}
|
}
|
||||||
XMEMSET(&local[md5->buffLen], 0, MD5_PAD_SIZE - md5->buffLen);
|
XMEMSET(&local[md5->buffLen], 0, MD5_PAD_SIZE - md5->buffLen);
|
||||||
@ -327,14 +337,14 @@ void Md5Final(Md5* md5, byte* hash)
|
|||||||
md5->loLen = md5->loLen << 3;
|
md5->loLen = md5->loLen << 3;
|
||||||
|
|
||||||
/* store lengths */
|
/* store lengths */
|
||||||
#ifdef BIG_ENDIAN_ORDER
|
#if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||||
ByteReverseBytes(local, local, MD5_BLOCK_SIZE);
|
ByteReverseBytes(local, local, MD5_BLOCK_SIZE);
|
||||||
#endif
|
#endif
|
||||||
/* ! length ordering dependent on digest endian type ! */
|
/* ! length ordering dependent on digest endian type ! */
|
||||||
XMEMCPY(&local[MD5_PAD_SIZE], &md5->loLen, sizeof(word32));
|
XMEMCPY(&local[MD5_PAD_SIZE], &md5->loLen, sizeof(word32));
|
||||||
XMEMCPY(&local[MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32));
|
XMEMCPY(&local[MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32));
|
||||||
|
|
||||||
Transform(md5);
|
XTRANSFORM(md5, local);
|
||||||
#ifdef BIG_ENDIAN_ORDER
|
#ifdef BIG_ENDIAN_ORDER
|
||||||
ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE);
|
ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE);
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,6 +35,13 @@
|
|||||||
#include <ctaocrypt/src/misc.c>
|
#include <ctaocrypt/src/misc.c>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FREESCALE_MMCAU
|
||||||
|
#include "cau_api.h"
|
||||||
|
#define XTRANSFORM(S,B) cau_sha1_hash_n((B), 1, ((S))->digest)
|
||||||
|
#else
|
||||||
|
#define XTRANSFORM(S,B) Transform((S))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef STM32F2_HASH
|
#ifdef STM32F2_HASH
|
||||||
/*
|
/*
|
||||||
@ -164,17 +171,23 @@
|
|||||||
|
|
||||||
void InitSha(Sha* sha)
|
void InitSha(Sha* sha)
|
||||||
{
|
{
|
||||||
sha->digest[0] = 0x67452301L;
|
#ifdef FREESCALE_MMCAU
|
||||||
sha->digest[1] = 0xEFCDAB89L;
|
cau_sha1_initialize_output(sha->digest);
|
||||||
sha->digest[2] = 0x98BADCFEL;
|
#else
|
||||||
sha->digest[3] = 0x10325476L;
|
sha->digest[0] = 0x67452301L;
|
||||||
sha->digest[4] = 0xC3D2E1F0L;
|
sha->digest[1] = 0xEFCDAB89L;
|
||||||
|
sha->digest[2] = 0x98BADCFEL;
|
||||||
|
sha->digest[3] = 0x10325476L;
|
||||||
|
sha->digest[4] = 0xC3D2E1F0L;
|
||||||
|
#endif
|
||||||
|
|
||||||
sha->buffLen = 0;
|
sha->buffLen = 0;
|
||||||
sha->loLen = 0;
|
sha->loLen = 0;
|
||||||
sha->hiLen = 0;
|
sha->hiLen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef FREESCALE_MMCAU
|
||||||
|
|
||||||
#define blk0(i) (W[i] = sha->buffer[i])
|
#define blk0(i) (W[i] = sha->buffer[i])
|
||||||
#define blk1(i) (W[i&15] = \
|
#define blk1(i) (W[i&15] = \
|
||||||
rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
|
rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
|
||||||
@ -272,6 +285,8 @@ static void Transform(Sha* sha)
|
|||||||
sha->digest[4] += e;
|
sha->digest[4] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* FREESCALE_MMCAU */
|
||||||
|
|
||||||
|
|
||||||
static INLINE void AddLength(Sha* sha, word32 len)
|
static INLINE void AddLength(Sha* sha, word32 len)
|
||||||
{
|
{
|
||||||
@ -295,10 +310,10 @@ void ShaUpdate(Sha* sha, const byte* data, word32 len)
|
|||||||
len -= add;
|
len -= add;
|
||||||
|
|
||||||
if (sha->buffLen == SHA_BLOCK_SIZE) {
|
if (sha->buffLen == SHA_BLOCK_SIZE) {
|
||||||
#ifdef LITTLE_ENDIAN_ORDER
|
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||||
ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
|
ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
|
||||||
#endif
|
#endif
|
||||||
Transform(sha);
|
XTRANSFORM(sha, local);
|
||||||
AddLength(sha, SHA_BLOCK_SIZE);
|
AddLength(sha, SHA_BLOCK_SIZE);
|
||||||
sha->buffLen = 0;
|
sha->buffLen = 0;
|
||||||
}
|
}
|
||||||
@ -310,7 +325,7 @@ void ShaFinal(Sha* sha, byte* hash)
|
|||||||
{
|
{
|
||||||
byte* local = (byte*)sha->buffer;
|
byte* local = (byte*)sha->buffer;
|
||||||
|
|
||||||
AddLength(sha, sha->buffLen); /* before adding pads */
|
AddLength(sha, sha->buffLen); /* before adding pads */
|
||||||
|
|
||||||
local[sha->buffLen++] = 0x80; /* add 1 */
|
local[sha->buffLen++] = 0x80; /* add 1 */
|
||||||
|
|
||||||
@ -319,10 +334,10 @@ void ShaFinal(Sha* sha, byte* hash)
|
|||||||
XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen);
|
XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen);
|
||||||
sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen;
|
sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen;
|
||||||
|
|
||||||
#ifdef LITTLE_ENDIAN_ORDER
|
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||||
ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
|
ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
|
||||||
#endif
|
#endif
|
||||||
Transform(sha);
|
XTRANSFORM(sha, local);
|
||||||
sha->buffLen = 0;
|
sha->buffLen = 0;
|
||||||
}
|
}
|
||||||
XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen);
|
XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen);
|
||||||
@ -333,14 +348,20 @@ void ShaFinal(Sha* sha, byte* hash)
|
|||||||
sha->loLen = sha->loLen << 3;
|
sha->loLen = sha->loLen << 3;
|
||||||
|
|
||||||
/* store lengths */
|
/* store lengths */
|
||||||
#ifdef LITTLE_ENDIAN_ORDER
|
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||||
ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
|
ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
|
||||||
#endif
|
#endif
|
||||||
/* ! length ordering dependent on digest endian type ! */
|
/* ! length ordering dependent on digest endian type ! */
|
||||||
XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));
|
XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));
|
||||||
XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));
|
XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));
|
||||||
|
|
||||||
Transform(sha);
|
#ifdef FREESCALE_MMCAU
|
||||||
|
/* Kinetis requires only these bytes reversed */
|
||||||
|
ByteReverseBytes(&local[SHA_PAD_SIZE], &local[SHA_PAD_SIZE],
|
||||||
|
2 * sizeof(word32));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
XTRANSFORM(sha, local);
|
||||||
#ifdef LITTLE_ENDIAN_ORDER
|
#ifdef LITTLE_ENDIAN_ORDER
|
||||||
ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
|
ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,6 +37,13 @@
|
|||||||
#include <ctaocrypt/src/misc.c>
|
#include <ctaocrypt/src/misc.c>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FREESCALE_MMCAU
|
||||||
|
#include "cau_api.h"
|
||||||
|
#define XTRANSFORM(S,B) cau_sha256_hash_n((B), 1, ((S))->digest)
|
||||||
|
#else
|
||||||
|
#define XTRANSFORM(S,B) Transform((S))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef min
|
#ifndef min
|
||||||
|
|
||||||
@ -50,20 +57,26 @@
|
|||||||
|
|
||||||
void InitSha256(Sha256* sha256)
|
void InitSha256(Sha256* sha256)
|
||||||
{
|
{
|
||||||
sha256->digest[0] = 0x6A09E667L;
|
#ifdef FREESCALE_MMCAU
|
||||||
sha256->digest[1] = 0xBB67AE85L;
|
cau_sha256_initialize_output(sha256->digest);
|
||||||
sha256->digest[2] = 0x3C6EF372L;
|
#else
|
||||||
sha256->digest[3] = 0xA54FF53AL;
|
sha256->digest[0] = 0x6A09E667L;
|
||||||
sha256->digest[4] = 0x510E527FL;
|
sha256->digest[1] = 0xBB67AE85L;
|
||||||
sha256->digest[5] = 0x9B05688CL;
|
sha256->digest[2] = 0x3C6EF372L;
|
||||||
sha256->digest[6] = 0x1F83D9ABL;
|
sha256->digest[3] = 0xA54FF53AL;
|
||||||
sha256->digest[7] = 0x5BE0CD19L;
|
sha256->digest[4] = 0x510E527FL;
|
||||||
|
sha256->digest[5] = 0x9B05688CL;
|
||||||
|
sha256->digest[6] = 0x1F83D9ABL;
|
||||||
|
sha256->digest[7] = 0x5BE0CD19L;
|
||||||
|
#endif
|
||||||
|
|
||||||
sha256->buffLen = 0;
|
sha256->buffLen = 0;
|
||||||
sha256->loLen = 0;
|
sha256->loLen = 0;
|
||||||
sha256->hiLen = 0;
|
sha256->hiLen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef FREESCALE_MMCAU
|
||||||
|
|
||||||
static const word32 K[64] = {
|
static const word32 K[64] = {
|
||||||
0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
|
0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
|
||||||
0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
|
0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
|
||||||
@ -128,6 +141,8 @@ static void Transform(Sha256* sha256)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* FREESCALE_MMCAU */
|
||||||
|
|
||||||
|
|
||||||
static INLINE void AddLength(Sha256* sha256, word32 len)
|
static INLINE void AddLength(Sha256* sha256, word32 len)
|
||||||
{
|
{
|
||||||
@ -151,10 +166,10 @@ void Sha256Update(Sha256* sha256, const byte* data, word32 len)
|
|||||||
len -= add;
|
len -= add;
|
||||||
|
|
||||||
if (sha256->buffLen == SHA256_BLOCK_SIZE) {
|
if (sha256->buffLen == SHA256_BLOCK_SIZE) {
|
||||||
#ifdef LITTLE_ENDIAN_ORDER
|
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||||
ByteReverseBytes(local, local, SHA256_BLOCK_SIZE);
|
ByteReverseBytes(local, local, SHA256_BLOCK_SIZE);
|
||||||
#endif
|
#endif
|
||||||
Transform(sha256);
|
XTRANSFORM(sha256, local);
|
||||||
AddLength(sha256, SHA256_BLOCK_SIZE);
|
AddLength(sha256, SHA256_BLOCK_SIZE);
|
||||||
sha256->buffLen = 0;
|
sha256->buffLen = 0;
|
||||||
}
|
}
|
||||||
@ -168,17 +183,17 @@ void Sha256Final(Sha256* sha256, byte* hash)
|
|||||||
|
|
||||||
AddLength(sha256, sha256->buffLen); /* before adding pads */
|
AddLength(sha256, sha256->buffLen); /* before adding pads */
|
||||||
|
|
||||||
local[sha256->buffLen++] = 0x80; /* add 1 */
|
local[sha256->buffLen++] = 0x80; /* add 1 */
|
||||||
|
|
||||||
/* pad with zeros */
|
/* pad with zeros */
|
||||||
if (sha256->buffLen > SHA256_PAD_SIZE) {
|
if (sha256->buffLen > SHA256_PAD_SIZE) {
|
||||||
XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen);
|
XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen);
|
||||||
sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen;
|
sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen;
|
||||||
|
|
||||||
#ifdef LITTLE_ENDIAN_ORDER
|
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||||
ByteReverseBytes(local, local, SHA256_BLOCK_SIZE);
|
ByteReverseBytes(local, local, SHA256_BLOCK_SIZE);
|
||||||
#endif
|
#endif
|
||||||
Transform(sha256);
|
XTRANSFORM(sha256, local);
|
||||||
sha256->buffLen = 0;
|
sha256->buffLen = 0;
|
||||||
}
|
}
|
||||||
XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen);
|
XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen);
|
||||||
@ -189,7 +204,7 @@ void Sha256Final(Sha256* sha256, byte* hash)
|
|||||||
sha256->loLen = sha256->loLen << 3;
|
sha256->loLen = sha256->loLen << 3;
|
||||||
|
|
||||||
/* store lengths */
|
/* store lengths */
|
||||||
#ifdef LITTLE_ENDIAN_ORDER
|
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||||
ByteReverseBytes(local, local, SHA256_BLOCK_SIZE);
|
ByteReverseBytes(local, local, SHA256_BLOCK_SIZE);
|
||||||
#endif
|
#endif
|
||||||
/* ! length ordering dependent on digest endian type ! */
|
/* ! length ordering dependent on digest endian type ! */
|
||||||
@ -197,7 +212,13 @@ void Sha256Final(Sha256* sha256, byte* hash)
|
|||||||
XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
|
XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
|
||||||
sizeof(word32));
|
sizeof(word32));
|
||||||
|
|
||||||
Transform(sha256);
|
#ifdef FREESCALE_MMCAU
|
||||||
|
/* Kinetis requires only these bytes reversed */
|
||||||
|
ByteReverseBytes(&local[SHA256_PAD_SIZE], &local[SHA256_PAD_SIZE],
|
||||||
|
2 * sizeof(word32));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
XTRANSFORM(sha256, local);
|
||||||
#ifdef LITTLE_ENDIAN_ORDER
|
#ifdef LITTLE_ENDIAN_ORDER
|
||||||
ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE);
|
ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE);
|
||||||
#endif
|
#endif
|
||||||
|
@ -217,6 +217,11 @@ enum {
|
|||||||
#define XISALPHA(c) isalpha((c))
|
#define XISALPHA(c) isalpha((c))
|
||||||
#endif
|
#endif
|
||||||
/* needed by CyaSSL_check_domain_name() */
|
/* needed by CyaSSL_check_domain_name() */
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
/* Cygwin uses a macro version of tolower() by default, use the
|
||||||
|
* function version. */
|
||||||
|
#undef tolower
|
||||||
|
#endif
|
||||||
#define XTOLOWER(c) tolower((c))
|
#define XTOLOWER(c) tolower((c))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -505,10 +505,14 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
|||||||
|
|
||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
if (useOcsp) {
|
if (useOcsp) {
|
||||||
CyaSSL_CTX_OCSP_set_options(ctx,
|
if (ocspUrl != NULL) {
|
||||||
CYASSL_OCSP_ENABLE | CYASSL_OCSP_NO_NONCE);
|
|
||||||
if (ocspUrl != NULL)
|
|
||||||
CyaSSL_CTX_OCSP_set_override_url(ctx, ocspUrl);
|
CyaSSL_CTX_OCSP_set_override_url(ctx, ocspUrl);
|
||||||
|
CyaSSL_CTX_OCSP_set_options(ctx, CYASSL_OCSP_ENABLE |
|
||||||
|
CYASSL_OCSP_URL_OVERRIDE | CYASSL_OCSP_NO_NONCE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CyaSSL_CTX_OCSP_set_options(ctx, CYASSL_OCSP_ENABLE |
|
||||||
|
CYASSL_OCSP_NO_NONCE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -459,10 +459,14 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
if (useOcsp) {
|
if (useOcsp) {
|
||||||
CyaSSL_CTX_OCSP_set_options(ctx,
|
if (ocspUrl != NULL) {
|
||||||
CYASSL_OCSP_ENABLE | CYASSL_OCSP_NO_NONCE);
|
|
||||||
if (ocspUrl != NULL)
|
|
||||||
CyaSSL_CTX_OCSP_set_override_url(ctx, ocspUrl);
|
CyaSSL_CTX_OCSP_set_override_url(ctx, ocspUrl);
|
||||||
|
CyaSSL_CTX_OCSP_set_options(ctx, CYASSL_OCSP_ENABLE |
|
||||||
|
CYASSL_OCSP_URL_OVERRIDE | CYASSL_OCSP_NO_NONCE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CyaSSL_CTX_OCSP_set_options(ctx, CYASSL_OCSP_ENABLE |
|
||||||
|
CYASSL_OCSP_NO_NONCE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_PK_CALLBACKS
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
85
src/io.c
85
src/io.c
@ -512,52 +512,62 @@ int EmbedGenerateCookie(CYASSL* ssl, byte *buf, int sz, void *ctx)
|
|||||||
|
|
||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
|
|
||||||
#ifdef TEST_IPV6
|
|
||||||
typedef struct sockaddr_in6 SOCKADDR_IN_T;
|
|
||||||
#define AF_INET_V AF_INET6
|
|
||||||
#else
|
|
||||||
typedef struct sockaddr_in SOCKADDR_IN_T;
|
|
||||||
#define AF_INET_V AF_INET
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
static int tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port)
|
||||||
static INLINE int tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port)
|
|
||||||
{
|
{
|
||||||
SOCKADDR_IN_T addr;
|
struct sockaddr_storage addr;
|
||||||
const char* host = ip;
|
int sockaddr_len = sizeof(struct sockaddr_in);
|
||||||
|
XMEMSET(&addr, 0, sizeof(addr));
|
||||||
|
|
||||||
/* peer could be in human readable form */
|
#ifdef HAVE_GETADDRINFO
|
||||||
if (ip != INADDR_ANY && isalpha(ip[0])) {
|
{
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo* answer = NULL;
|
||||||
|
char strPort[8];
|
||||||
|
|
||||||
|
XMEMSET(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
XSNPRINTF(strPort, sizeof(strPort), "%d", port);
|
||||||
|
strPort[7] = '\0';
|
||||||
|
|
||||||
|
if (getaddrinfo(ip, strPort, &hints, &answer) < 0 || answer == NULL) {
|
||||||
|
CYASSL_MSG("no addr info for OCSP responder");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_len = answer->ai_addrlen;
|
||||||
|
XMEMCPY(&addr, answer->ai_addr, sockaddr_len);
|
||||||
|
freeaddrinfo(answer);
|
||||||
|
|
||||||
|
}
|
||||||
|
#else /* HAVE_GETADDRINFO */
|
||||||
|
{
|
||||||
struct hostent* entry = gethostbyname(ip);
|
struct hostent* entry = gethostbyname(ip);
|
||||||
|
struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
|
||||||
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
struct sockaddr_in tmp;
|
sin->sin_family = AF_INET;
|
||||||
XMEMSET(&tmp, 0, sizeof(struct sockaddr_in));
|
sin->sin_port = htons(port);
|
||||||
XMEMCPY(&tmp.sin_addr.s_addr, entry->h_addr_list[0],
|
XMEMCPY(&sin->sin_addr.s_addr, entry->h_addr_list[0],
|
||||||
entry->h_length);
|
entry->h_length);
|
||||||
host = inet_ntoa(tmp.sin_addr);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CYASSL_MSG("no addr entry for OCSP responder");
|
CYASSL_MSG("no addr info for OCSP responder");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_GETADDRINFO */
|
||||||
|
|
||||||
*sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
|
*sockfd = socket(addr.ss_family, SOCK_STREAM, 0);
|
||||||
if (*sockfd < 0) {
|
if (*sockfd < 0) {
|
||||||
CYASSL_MSG("bad socket fd, out of fds?");
|
CYASSL_MSG("bad socket fd, out of fds?");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
XMEMSET(&addr, 0, sizeof(SOCKADDR_IN_T));
|
|
||||||
|
|
||||||
addr.sin_family = AF_INET_V;
|
if (connect(*sockfd, (struct sockaddr *)&addr, sockaddr_len) != 0) {
|
||||||
addr.sin_port = htons(port);
|
|
||||||
if (host == INADDR_ANY)
|
|
||||||
addr.sin_addr.s_addr = INADDR_ANY;
|
|
||||||
else
|
|
||||||
addr.sin_addr.s_addr = inet_addr(host);
|
|
||||||
|
|
||||||
if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) {
|
|
||||||
CYASSL_MSG("OCSP responder tcp connect failed");
|
CYASSL_MSG("OCSP responder tcp connect failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -597,15 +607,26 @@ static int decode_url(const char* url, int urlSz,
|
|||||||
int i, cur;
|
int i, cur;
|
||||||
|
|
||||||
/* need to break the url down into scheme, address, and port */
|
/* need to break the url down into scheme, address, and port */
|
||||||
/* "http://example.com:8080/" */
|
/* "http://example.com:8080/" */
|
||||||
|
/* "http://[::1]:443/" */
|
||||||
if (XSTRNCMP(url, "http://", 7) == 0) {
|
if (XSTRNCMP(url, "http://", 7) == 0) {
|
||||||
cur = 7;
|
cur = 7;
|
||||||
} else cur = 0;
|
} else cur = 0;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (url[cur] != 0 && url[cur] != ':' &&
|
if (url[cur] == '[') {
|
||||||
|
cur++;
|
||||||
|
/* copy until ']' */
|
||||||
|
while (url[cur] != 0 && url[cur] != ']' && cur < urlSz) {
|
||||||
|
outName[i++] = url[cur++];
|
||||||
|
}
|
||||||
|
cur++; /* skip ']' */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (url[cur] != 0 && url[cur] != ':' &&
|
||||||
url[cur] != '/' && cur < urlSz) {
|
url[cur] != '/' && cur < urlSz) {
|
||||||
outName[i++] = url[cur++];
|
outName[i++] = url[cur++];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
outName[i] = 0;
|
outName[i] = 0;
|
||||||
/* Need to pick out the path after the domain name */
|
/* Need to pick out the path after the domain name */
|
||||||
|
Reference in New Issue
Block a user