diff --git a/configure.ac b/configure.ac index 202b3e6e5..037fbf5ba 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ # # -AC_INIT([cyassl],[2.0.9],[http://www.yassl.com]) +AC_INIT([cyassl],[2.1.0],[http://www.yassl.com]) AC_CONFIG_AUX_DIR(config) diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index 48879a6e1..e58f6c0ca 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -832,8 +832,20 @@ int AES_set_decrypt_key (const unsigned char* userKey, const int bits, #endif /* CYASSL_AESNI */ +int AesSetIV(Aes* aes, const byte* iv) +{ + if (aes == NULL) + return BAD_FUNC_ARG; + + if (iv) + XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); + + return 0; +} + + int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, - int dir) + int dir) { word32 temp, *rk = aes->key; unsigned int i = 0; @@ -976,10 +988,8 @@ int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff]; } } - if (iv) - XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); - return 0; + return AesSetIV(aes, iv); } diff --git a/ctaocrypt/src/sha512.c b/ctaocrypt/src/sha512.c index 551927a0a..f14efecff 100644 --- a/ctaocrypt/src/sha512.c +++ b/ctaocrypt/src/sha512.c @@ -128,6 +128,11 @@ static const word64 K512[80] = { #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk0(i));\ d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) +#define blk384(i) (W[i] = sha384->buffer[i]) + +#define R2(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk384(i));\ + d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) + static void Transform(Sha512* sha512) { @@ -209,7 +214,7 @@ void Sha512Final(Sha512* sha512, byte* hash) /* pad with zeros */ if (sha512->buffLen > SHA512_PAD_SIZE) { - XMEMSET(&local[sha512->buffLen], 0, SHA512_BLOCK_SIZE - sha512->buffLen); + XMEMSET(&local[sha512->buffLen], 0, SHA512_BLOCK_SIZE -sha512->buffLen); sha512->buffLen += SHA512_BLOCK_SIZE - sha512->buffLen; #ifdef LITTLE_ENDIAN_ORDER @@ -243,4 +248,139 @@ void Sha512Final(Sha512* sha512, byte* hash) } + +#ifdef CYASSL_SHA384 + +void InitSha384(Sha384* sha384) +{ + sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8); + sha384->digest[1] = W64LIT(0x629a292a367cd507); + sha384->digest[2] = W64LIT(0x9159015a3070dd17); + sha384->digest[3] = W64LIT(0x152fecd8f70e5939); + sha384->digest[4] = W64LIT(0x67332667ffc00b31); + sha384->digest[5] = W64LIT(0x8eb44a8768581511); + sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7); + sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4); + + sha384->buffLen = 0; + sha384->loLen = 0; + sha384->hiLen = 0; +} + + +static void Transform384(Sha384* sha384) +{ + const word64* K = K512; + + word32 j; + word64 W[16]; + word64 T[8]; + + /* Copy digest to working vars */ + XMEMCPY(T, sha384->digest, sizeof(T)); + + /* 64 operations, partially loop unrolled */ + for (j = 0; j < 80; j += 16) { + R2( 0); R2( 1); R2( 2); R2( 3); + R2( 4); R2( 5); R2( 6); R2( 7); + R2( 8); R2( 9); R2(10); R2(11); + R2(12); R2(13); R2(14); R2(15); + } + + /* Add the working vars back into digest */ + + sha384->digest[0] += a(0); + sha384->digest[1] += b(0); + sha384->digest[2] += c(0); + sha384->digest[3] += d(0); + sha384->digest[4] += e(0); + sha384->digest[5] += f(0); + sha384->digest[6] += g(0); + sha384->digest[7] += h(0); + + /* Wipe variables */ + XMEMSET(W, 0, sizeof(W)); + XMEMSET(T, 0, sizeof(T)); +} + + +static INLINE void AddLength384(Sha384* sha384, word32 len) +{ + word32 tmp = sha384->loLen; + if ( (sha384->loLen += len) < tmp) + sha384->hiLen++; /* carry low to high */ +} + + +void Sha384Update(Sha384* sha384, const byte* data, word32 len) +{ + /* do block size increments */ + byte* local = (byte*)sha384->buffer; + + while (len) { + word32 add = min(len, SHA384_BLOCK_SIZE - sha384->buffLen); + XMEMCPY(&local[sha384->buffLen], data, add); + + sha384->buffLen += add; + data += add; + len -= add; + + if (sha384->buffLen == SHA384_BLOCK_SIZE) { + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords64(sha384->buffer, sha384->buffer, + SHA384_BLOCK_SIZE); + #endif + Transform384(sha384); + AddLength384(sha384, SHA384_BLOCK_SIZE); + sha384->buffLen = 0; + } + } +} + + +void Sha384Final(Sha384* sha384, byte* hash) +{ + byte* local = (byte*)sha384->buffer; + + AddLength384(sha384, sha384->buffLen); /* before adding pads */ + + local[sha384->buffLen++] = 0x80; /* add 1 */ + + /* pad with zeros */ + if (sha384->buffLen > SHA384_PAD_SIZE) { + XMEMSET(&local[sha384->buffLen], 0, SHA384_BLOCK_SIZE -sha384->buffLen); + sha384->buffLen += SHA384_BLOCK_SIZE - sha384->buffLen; + + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords64(sha384->buffer,sha384->buffer,SHA384_BLOCK_SIZE); + #endif + Transform384(sha384); + sha384->buffLen = 0; + } + XMEMSET(&local[sha384->buffLen], 0, SHA384_PAD_SIZE - sha384->buffLen); + + /* put lengths in bits */ + sha384->hiLen = (sha384->loLen >> (8*sizeof(sha384->loLen) - 3)) + + (sha384->hiLen << 3); + sha384->loLen = sha384->loLen << 3; + + /* store lengths */ + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords64(sha384->buffer, sha384->buffer, SHA384_PAD_SIZE); + #endif + /* ! length ordering dependent on digest endian type ! */ + sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 2] = sha384->hiLen; + sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 1] = sha384->loLen; + + Transform384(sha384); + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords64(sha384->digest, sha384->digest, SHA384_DIGEST_SIZE); + #endif + XMEMCPY(hash, sha384->digest, SHA384_DIGEST_SIZE); + + InitSha384(sha384); /* reset state */ +} + +#endif /* CYASSL_SHA384 */ + #endif /* CYASSL_SHA512 */ diff --git a/cyassl/ctaocrypt/aes.h b/cyassl/ctaocrypt/aes.h index 61022a03b..c3356de4a 100644 --- a/cyassl/ctaocrypt/aes.h +++ b/cyassl/ctaocrypt/aes.h @@ -54,6 +54,7 @@ enum { + AES_ENC_TYPE = 1, /* cipher unique type */ AES_ENCRYPTION = 0, AES_DECRYPTION = 1, AES_BLOCK_SIZE = 16 @@ -72,6 +73,7 @@ typedef struct Aes { CYASSL_API int AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv, int dir); +CYASSL_API int AesSetIV(Aes* aes, const byte* iv); CYASSL_API void AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); CYASSL_API void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz); CYASSL_API void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); diff --git a/cyassl/ctaocrypt/sha512.h b/cyassl/ctaocrypt/sha512.h index e5a42ac3d..79861afee 100644 --- a/cyassl/ctaocrypt/sha512.h +++ b/cyassl/ctaocrypt/sha512.h @@ -56,6 +56,33 @@ CYASSL_API void Sha512Update(Sha512*, const byte*, word32); CYASSL_API void Sha512Final(Sha512*, byte*); +#ifdef CYASSL_SHA384 + +/* in bytes */ +enum { + SHA384 = 5, /* hash type unique */ + SHA384_BLOCK_SIZE = 128, + SHA384_DIGEST_SIZE = 48, + SHA384_PAD_SIZE = 112 +}; + + +/* Sha384 digest */ +typedef struct Sha384 { + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word64 digest[SHA512_DIGEST_SIZE / sizeof(word64)]; /* for transform 512 */ + word64 buffer[SHA384_BLOCK_SIZE / sizeof(word64)]; +} Sha384; + + +CYASSL_API void InitSha384(Sha384*); +CYASSL_API void Sha384Update(Sha384*, const byte*, word32); +CYASSL_API void Sha384Final(Sha384*, byte*); + +#endif /* CYASSL_SHA384 */ + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/cyassl/openssl/ripemd.h b/cyassl/openssl/ripemd.h new file mode 100644 index 000000000..2d4d01466 --- /dev/null +++ b/cyassl/openssl/ripemd.h @@ -0,0 +1,37 @@ +/* ripemd.h for openssl */ + + +#ifndef CYASSL_RIPEMD_H_ +#define CYASSL_RIPEMD_H_ + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct CYASSL_RIPEMD_CTX { + int holder[32]; /* big enough to hold ctaocrypt, but check on init */ +} CYASSL_RIPEMD_CTX; + +CYASSL_API void CyaSSL_RIPEMD_Init(CYASSL_RIPEMD_CTX*); +CYASSL_API void CyaSSL_RIPEMD_Update(CYASSL_RIPEMD_CTX*, const void*, + unsigned long); +CYASSL_API void CyaSSL_RIPEMD_Final(unsigned char*, CYASSL_RIPEMD_CTX*); + + +typedef CYASSL_RIPEMD_CTX RIPEMD_CTX; + +#define RIPEMD_Init CyaSSL_RIPEMD_Init +#define RIPEMD_Update CyaSSL_RIPEMD_Update +#define RIPEMD_Final CyaSSL_RIPEMD_Final + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* CYASSL_MD5_H_ */ + diff --git a/src/ssl.c b/src/ssl.c index d91e924f0..8d82a62bd 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -44,12 +44,17 @@ #include #include #include + #include /* openssl headers end, cyassl internal headers next */ #include #include #include #include #include + #include + #ifdef CYASSL_SHA512 + #include + #endif #endif #ifndef NO_FILESYSTEM @@ -3087,18 +3092,54 @@ int CyaSSL_set_compression(CYASSL* ssl) DYNAMIC_TYPE_OPENSSL); CYASSL_ENTER("BIO_new"); if (bio) { - bio->type = method->type; - bio->close = 0; - bio->eof = 0; - bio->ssl = 0; - bio->fd = 0; - bio->prev = 0; - bio->next = 0; + bio->type = method->type; + bio->close = 0; + bio->eof = 0; + bio->ssl = NULL; + bio->mem = NULL; + bio->memLen = 0; + bio->fd = 0; + bio->prev = NULL; + bio->next = NULL; } return bio; } + int CyaSSL_BIO_get_mem_data(CYASSL_BIO* bio, const byte** p) + { + if (bio == NULL || p == NULL) + return -1; + + *p = bio->mem; + + return bio->memLen; + } + + + CYASSL_BIO* CyaSSL_BIO_new_mem_buf(void* buf, int len) + { + CYASSL_BIO* bio = NULL; + if (buf == NULL) + return bio; + + bio = CyaSSL_BIO_new(CyaSSL_BIO_s_mem()); + if (bio == NULL) + return bio; + + bio->memLen = len; + bio->mem = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL); + if (bio->mem == NULL) { + XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL); + return NULL; + } + + XMEMCPY(bio->mem, buf, len); + + return bio; + } + + #ifdef USE_WINDOWS_API #define CloseSocket(s) closesocket(s) #else @@ -3116,6 +3157,8 @@ int CyaSSL_set_compression(CYASSL* ssl) if (bio->fd) CloseSocket(bio->fd); } + if (bio->mem) + XFREE(bio->mem, 0, DYNAMIC_TYPE_OPENSSL); XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL); } return 0; @@ -3428,6 +3471,89 @@ int CyaSSL_set_compression(CYASSL* ssl) } + void CyaSSL_SHA256_Init(CYASSL_SHA256_CTX* sha256) + { + typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(Sha256) ? 1 : -1]; + (void)sizeof(sha_test); + + CYASSL_ENTER("SHA256_Init"); + InitSha256((Sha256*)sha256); + } + + + void CyaSSL_SHA256_Update(CYASSL_SHA256_CTX* sha, const void* input, + unsigned long sz) + { + CYASSL_ENTER("SHA256_Update"); + Sha256Update((Sha256*)sha, (const byte*)input, sz); + } + + + void CyaSSL_SHA256_Final(byte* input, CYASSL_SHA256_CTX* sha) + { + CYASSL_ENTER("SHA256_Final"); + Sha256Final((Sha256*)sha, input); + } + + + #ifdef CYASSL_SHA384 + + void CyaSSL_SHA384_Init(CYASSL_SHA384_CTX* sha) + { + typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(Sha384) ? 1 : -1]; + (void)sizeof(sha_test); + + CYASSL_ENTER("SHA384_Init"); + InitSha384((Sha384*)sha); + } + + + void CyaSSL_SHA384_Update(CYASSL_SHA384_CTX* sha, const void* input, + unsigned long sz) + { + CYASSL_ENTER("SHA384_Update"); + Sha384Update((Sha384*)sha, (const byte*)input, sz); + } + + + void CyaSSL_SHA384_Final(byte* input, CYASSL_SHA384_CTX* sha) + { + CYASSL_ENTER("SHA384_Final"); + Sha384Final((Sha384*)sha, input); + } + + #endif /* CYASSL_SHA384 */ + + + #ifdef CYASSL_SHA512 + + void CyaSSL_SHA512_Init(CYASSL_SHA512_CTX* sha) + { + typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(Sha512) ? 1 : -1]; + (void)sizeof(sha_test); + + CYASSL_ENTER("SHA512_Init"); + InitSha512((Sha512*)sha); + } + + + void CyaSSL_SHA512_Update(CYASSL_SHA512_CTX* sha, const void* input, + unsigned long sz) + { + CYASSL_ENTER("SHA512_Update"); + Sha512Update((Sha512*)sha, (const byte*)input, sz); + } + + + void CyaSSL_SHA512_Final(byte* input, CYASSL_SHA512_CTX* sha) + { + CYASSL_ENTER("SHA512_Final"); + Sha512Final((Sha512*)sha, input); + } + + #endif /* CYASSL_SHA512 */ + + const CYASSL_EVP_MD* CyaSSL_EVP_md5(void) { static const char* type = "MD5"; @@ -3444,20 +3570,338 @@ int CyaSSL_set_compression(CYASSL* ssl) } + const CYASSL_EVP_MD* CyaSSL_EVP_sha256(void) + { + static const char* type = "SHA256"; + CYASSL_ENTER("EVP_sha256"); + return type; + } + + #ifdef CYASSL_SHA384 + + const CYASSL_EVP_MD* CyaSSL_EVP_sha384(void) + { + static const char* type = "SHA384"; + CYASSL_ENTER("EVP_sha384"); + return type; + } + + #endif /* CYASSL_SHA384 */ + + #ifdef CYASSL_SHA512 + + const CYASSL_EVP_MD* CyaSSL_EVP_sha512(void) + { + static const char* type = "SHA512"; + CYASSL_ENTER("EVP_sha512"); + return type; + } + + #endif /* CYASSL_SHA512 */ + + void CyaSSL_EVP_MD_CTX_init(CYASSL_EVP_MD_CTX* ctx) { + CYASSL_ENTER("EVP_CIPHER_MD_CTX_init"); (void)ctx; /* do nothing */ } + const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_128_cbc(void) + { + static const char* type = "AES128-CBC"; + CYASSL_ENTER("CyaSSL_EVP_aes_128_cbc"); + return type; + } + + + const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_192_cbc(void) + { + static const char* type = "AES192-CBC"; + CYASSL_ENTER("CyaSSL_EVP_aes_192_cbc"); + return type; + } + + + const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_256_cbc(void) + { + static const char* type = "AES256-CBC"; + CYASSL_ENTER("CyaSSL_EVP_aes_256_cbc"); + return type; + } + + + const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_128_ctr(void) + { + static const char* type = "AES128-CTR"; + CYASSL_ENTER("CyaSSL_EVP_aes_128_ctr"); + return type; + } + + + const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_192_ctr(void) + { + static const char* type = "AES192-CTR"; + CYASSL_ENTER("CyaSSL_EVP_aes_192_ctr"); + return type; + } + + + const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_256_ctr(void) + { + static const char* type = "AES256-CTR"; + CYASSL_ENTER("CyaSSL_EVP_aes_256_ctr"); + return type; + } + + + const CYASSL_EVP_CIPHER* CyaSSL_EVP_des_cbc(void) + { + static const char* type = "DES-CBC"; + CYASSL_ENTER("CyaSSL_EVP_des_cbc"); + return type; + } + + + const CYASSL_EVP_CIPHER* CyaSSL_EVP_des_ede3_cbc(void) + { + static const char* type = "DES-EDE3-CBC"; + CYASSL_ENTER("CyaSSL_EVP_des_ede3_cbc"); + return type; + } + + + const CYASSL_EVP_CIPHER* CyaSSL_EVP_rc4(void) + { + static const char* type = "ARC4"; + CYASSL_ENTER("CyaSSL_EVP_rc4"); + return type; + } + + int CyaSSL_EVP_MD_CTX_cleanup(CYASSL_EVP_MD_CTX* ctx) { CYASSL_ENTER("EVP_MD_CTX_cleanup"); (void)ctx; return 0; + } + + + + void CyaSSL_EVP_CIPHER_CTX_init(CYASSL_EVP_CIPHER_CTX* ctx) + { + CYASSL_ENTER("EVP_CIPHER_CTX_init"); + if (ctx) { + ctx->cipherType = 0xff; /* no init */ + ctx->keyLen = 0; + ctx->enc = 1; /* start in encrypt mode */ + } + } + + + int CyaSSL_EVP_CIPHER_CTX_cleanup(CYASSL_EVP_CIPHER_CTX* ctx) + { + CYASSL_ENTER("EVP_CIPHER_CTX_cleanup"); + if (ctx) { + ctx->cipherType = 0xff; /* no more init */ + ctx->keyLen = 0; + } + + return 1; /* success */ } + int CyaSSL_EVP_CipherInit(CYASSL_EVP_CIPHER_CTX* ctx, + const CYASSL_EVP_CIPHER* type, byte* key, + byte* iv, int enc) + { + CYASSL_ENTER("CyaSSL_EVP_CipherInit"); + if (ctx == NULL) + return 0; /* failure */ + + if (type == NULL && ctx->cipherType == 0xff) + return 0; /* failure */ + + if (ctx->cipherType == AES_128_CBC_TYPE || (type && + XSTRNCMP(type, "AES128-CBC", 10) == 0)) { + ctx->cipherType = AES_128_CBC_TYPE; + ctx->keyLen = 16; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) + AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + enc ? AES_ENCRYPTION : AES_DECRYPTION); + if (iv && key == NULL) + AesSetIV(&ctx->cipher.aes, iv); + } + else if (ctx->cipherType == AES_192_CBC_TYPE || (type && + XSTRNCMP(type, "AES192-CBC", 10) == 0)) { + ctx->cipherType = AES_192_CBC_TYPE; + ctx->keyLen = 24; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) + AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + enc ? AES_ENCRYPTION : AES_DECRYPTION); + if (iv && key == NULL) + AesSetIV(&ctx->cipher.aes, iv); + } + else if (ctx->cipherType == AES_256_CBC_TYPE || (type && + XSTRNCMP(type, "AES256-CBC", 10) == 0)) { + ctx->cipherType = AES_256_CBC_TYPE; + ctx->keyLen = 32; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) + AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + enc ? AES_ENCRYPTION : AES_DECRYPTION); + if (iv && key == NULL) + AesSetIV(&ctx->cipher.aes, iv); + } + else if (ctx->cipherType == AES_128_CTR_TYPE || (type && + XSTRNCMP(type, "AES128-CTR", 10) == 0)) { + ctx->cipherType = AES_128_CTR_TYPE; + ctx->keyLen = 16; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) + AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + enc ? AES_ENCRYPTION : AES_DECRYPTION); + if (iv && key == NULL) + AesSetIV(&ctx->cipher.aes, iv); + } + else if (ctx->cipherType == AES_192_CTR_TYPE || (type && + XSTRNCMP(type, "AES192-CTR", 10) == 0)) { + ctx->cipherType = AES_192_CTR_TYPE; + ctx->keyLen = 24; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) + AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + enc ? AES_ENCRYPTION : AES_DECRYPTION); + if (iv && key == NULL) + AesSetIV(&ctx->cipher.aes, iv); + } + else if (ctx->cipherType == AES_256_CTR_TYPE || (type && + XSTRNCMP(type, "AES256-CTR", 10) == 0)) { + ctx->cipherType = AES_256_CTR_TYPE; + ctx->keyLen = 32; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) + AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + enc ? AES_ENCRYPTION : AES_DECRYPTION); + if (iv && key == NULL) + AesSetIV(&ctx->cipher.aes, iv); + } + else if (ctx->cipherType == DES_CBC_TYPE || (type && + XSTRNCMP(type, "DES-CBC", 7) == 0)) { + ctx->cipherType = DES_CBC_TYPE; + ctx->keyLen = 8; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) + Des_SetKey(&ctx->cipher.des, key, iv, + enc ? DES_ENCRYPTION : DES_DECRYPTION); + if (iv && key == NULL) + Des_SetIV(&ctx->cipher.des, iv); + } + else if (ctx->cipherType == DES_EDE3_CBC_TYPE || (type && + XSTRNCMP(type, "DES-EDE3-CBC", 11) == 0)) { + ctx->cipherType = DES_EDE3_CBC_TYPE; + ctx->keyLen = 24; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) + Des3_SetKey(&ctx->cipher.des3, key, iv, + enc ? DES_ENCRYPTION : DES_DECRYPTION); + if (iv && key == NULL) + Des3_SetIV(&ctx->cipher.des3, iv); + } + else if (ctx->cipherType == ARC4_TYPE || (type && + XSTRNCMP(type, "ARC4", 4) == 0)) { + ctx->cipherType = ARC4_TYPE; + if (ctx->keyLen == 0) /* user may have already set */ + ctx->keyLen = 16; /* default to 128 */ + if (key) + Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen); + } + else + return 0; /* failure */ + + + return 1; /* success */ + } + + + int CyaSSL_EVP_CIPHER_CTX_key_length(CYASSL_EVP_CIPHER_CTX* ctx) + { + if (ctx) + return ctx->keyLen; + + return 0; /* failure */ + } + + + int CyaSSL_EVP_CIPHER_CTX_set_key_length(CYASSL_EVP_CIPHER_CTX* ctx, + int keylen) + { + if (ctx) + ctx->keyLen = keylen; + else + return 0; /* failure */ + + return 1; /* success */ + } + + + int CyaSSL_EVP_Cipher(CYASSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src, + word32 len) + { + if (ctx == NULL || dst == NULL || src == NULL) + return 0; /* failure */ + + if (ctx->cipherType == 0xff) + return 0; /* failure */ + + + switch (ctx->cipherType) { + + case AES_128_CBC_TYPE : + case AES_192_CBC_TYPE : + case AES_256_CBC_TYPE : + if (ctx->enc) + AesCbcEncrypt(&ctx->cipher.aes, dst, src, len); + else + AesCbcDecrypt(&ctx->cipher.aes, dst, src, len); + break; + + case DES_CBC_TYPE : + if (ctx->enc) + Des_CbcEncrypt(&ctx->cipher.des, dst, src, len); + else + Des_CbcDecrypt(&ctx->cipher.des, dst, src, len); + break; + + case DES_EDE3_CBC_TYPE : + if (ctx->enc) + Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len); + else + Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len); + break; + + case ARC4_TYPE : + Arc4Process(&ctx->cipher.arc4, dst, src, len); + break; + + default: + return 0; /* failure */ + } + + + return 1; /* success */ + } + int CyaSSL_EVP_DigestInit(CYASSL_EVP_MD_CTX* ctx, const CYASSL_EVP_MD* type) { @@ -3466,10 +3910,27 @@ int CyaSSL_set_compression(CYASSL* ssl) ctx->macType = MD5; CyaSSL_MD5_Init((MD5_CTX*)&ctx->hash); } + else if (XSTRNCMP(type, "SHA256", 6) == 0) { + ctx->macType = SHA256; + CyaSSL_SHA256_Init((SHA256_CTX*)&ctx->hash); + } + #ifdef CYASSL_SHA384 + else if (XSTRNCMP(type, "SHA384", 6) == 0) { + ctx->macType = SHA384; + CyaSSL_SHA384_Init((SHA384_CTX*)&ctx->hash); + } + #endif + #ifdef CYASSL_SHA512 + else if (XSTRNCMP(type, "SHA512", 6) == 0) { + ctx->macType = SHA512; + CyaSSL_SHA512_Init((SHA512_CTX*)&ctx->hash); + } + #endif + /* has to be last since would pick or 256, 384, or 512 too */ else if (XSTRNCMP(type, "SHA", 3) == 0) { ctx->macType = SHA; CyaSSL_SHA_Init((SHA_CTX*)&ctx->hash); - } + } else return BAD_FUNC_ARG; @@ -3485,6 +3946,19 @@ int CyaSSL_set_compression(CYASSL* ssl) CyaSSL_MD5_Update((MD5_CTX*)&ctx->hash, data, (unsigned long)sz); else if (ctx->macType == SHA) CyaSSL_SHA_Update((SHA_CTX*)&ctx->hash, data, (unsigned long)sz); + else if (ctx->macType == SHA256) + CyaSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data, + (unsigned long)sz); + #ifdef CYASSL_SHA384 + else if (ctx->macType == SHA384) + CyaSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data, + (unsigned long)sz); + #endif + #ifdef CYASSL_SHA512 + else if (ctx->macType == SHA512) + CyaSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data, + (unsigned long)sz); + #endif else return BAD_FUNC_ARG; @@ -3504,6 +3978,22 @@ int CyaSSL_set_compression(CYASSL* ssl) CyaSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash); if (s) *s = SHA_DIGEST_SIZE; } + else if (ctx->macType == SHA256) { + CyaSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash); + if (s) *s = SHA_DIGEST_SIZE; + } + #ifdef CYASSL_SHA384 + else if (ctx->macType == SHA384) { + CyaSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash); + if (s) *s = SHA_DIGEST_SIZE; + } + #endif + #ifdef CYASSL_SHA512 + else if (ctx->macType == SHA512) { + CyaSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash); + if (s) *s = SHA_DIGEST_SIZE; + } + #endif else return BAD_FUNC_ARG; @@ -3571,6 +4061,17 @@ int CyaSSL_set_compression(CYASSL* ssl) } + void CyaSSL_RAND_add(const void* add, int len, double entropy) + { + (void)add; + (void)len; + (void)entropy; + + /* CyaSSL seeds/adds internally, use explicit RNG if you want + to take control */ + } + + int CyaSSL_DES_key_sched(CYASSL_const_DES_cblock* key, CYASSL_DES_key_schedule* schedule) { @@ -4020,7 +4521,12 @@ int CyaSSL_set_compression(CYASSL* ssl) CYASSL_BIO_METHOD* CyaSSL_BIO_s_mem(void) { - return 0; + static CYASSL_BIO_METHOD meth; + + CYASSL_ENTER("BIO_s_mem"); + meth.type = BIO_MEMORY; + + return &meth; }