diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 13:58:15 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 13:58:15 +0100 |
commit | 4aca87515a5083ae0e31ce3177189fd43b6d05ac (patch) | |
tree | 7b1d9a31393ca090757dc6f0d3859b4fcd93f271 /release/src/router/matrixssl/src/cipherSuite.c | |
parent | 008d0be72b2f160382c6e880765e96b64a050c65 (diff) | |
download | tomato-4aca87515a5083ae0e31ce3177189fd43b6d05ac.tar.gz tomato-4aca87515a5083ae0e31ce3177189fd43b6d05ac.tar.bz2 |
patch to Vanilla Tomato 1.28
Diffstat (limited to 'release/src/router/matrixssl/src/cipherSuite.c')
-rw-r--r-- | release/src/router/matrixssl/src/cipherSuite.c | 441 |
1 files changed, 441 insertions, 0 deletions
diff --git a/release/src/router/matrixssl/src/cipherSuite.c b/release/src/router/matrixssl/src/cipherSuite.c new file mode 100644 index 00000000..c61724ac --- /dev/null +++ b/release/src/router/matrixssl/src/cipherSuite.c @@ -0,0 +1,441 @@ +/* + * cipherSuite.c + * Release $Name: MATRIXSSL_1_8_8_OPEN $ + * + * Wrappers for the various cipher suites. + * Contributors should add additional cipher suites here. + * Enable specific suites at compile time in matrixConfig.h + */ +/* + * Copyright (c) PeerSec Networks, 2002-2009. All Rights Reserved. + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from PeerSec Networks + * at http://www.peersec.com + * + * This program is distributed in WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#include "matrixInternal.h" + +/******************************************************************************/ +/* + Using void *ssl rather than ssl_t *ssl is a workaround for a chicken-egg + issue in matrixInternal.h where these function prototypes are used + before ssl_t is defined. +*/ +#ifdef USE_SHA1_MAC +static int32 sha1GenerateMac(void *ssl, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac); +static int32 sha1VerifyMac(void *ssl, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac); +#endif + +#ifdef USE_MD5_MAC +static int32 md5GenerateMac(void *ssl, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac); +static int32 md5VerifyMac(void *ssl, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac); +#endif + +#ifdef USE_SSL_RSA_WITH_RC4_128_MD5 +static int32 matrixCipher4Init(sslSec_t *sec, int32 type); +#endif /* USE_SSL_RSA_WITH_RC4_128_MD5 */ + +#ifdef USE_SSL_RSA_WITH_RC4_128_SHA +static int32 matrixCipher5Init(sslSec_t *sec, int32 type); +#endif /* USE_SSL_RSA_WITH_RC4_128_SHA */ + +#ifdef USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA +static int32 matrixCipherAInit(sslSec_t *sec, int32 type); +#endif /* USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA */ + + + + +static int32 nullInit(sslSec_t *sec, int32 type); +static int32 nullEncrypt(sslCipherContext_t *ctx, unsigned char *in, + unsigned char *out, int32 len); +static int32 nullDecrypt(sslCipherContext_t *ctx, unsigned char *in, + unsigned char *out, int32 len); +static int32 nullEncryptPub(psPool_t *pool, sslRsaKey_t *key, + unsigned char *in, int32 inlen, + unsigned char *out, int32 outlen); +static int32 nullDecryptPriv(psPool_t *pool, sslRsaKey_t *key, + unsigned char *in, int32 inlen, + unsigned char *out, int32 outlen); +static int32 nullGenerateMac(void *ssl, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac); +static int32 nullVerifyMac(void *ssl, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac); + +/******************************************************************************/ + +static sslCipherSpec_t supportedCiphers[] = { +/* + New ciphers should be added here, similar to the ones below + These ciphers should be in order of the most desireable to the + least desireable ciphers to negotiate. +*/ +#ifdef USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA + {SSL_RSA_WITH_3DES_EDE_CBC_SHA, + 20, /* macSize */ + 24, /* keySize */ + 8, /* ivSize */ + 8, /* blocksize */ + matrixCipherAInit, + matrix3desEncrypt, + matrix3desDecrypt, + NULL, + matrixRsaDecryptPub, + matrixRsaEncryptPub, + matrixRsaDecryptPriv, + sha1GenerateMac, + sha1VerifyMac}, +#endif /* USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA */ +#ifdef USE_SSL_RSA_WITH_RC4_128_SHA + {SSL_RSA_WITH_RC4_128_SHA, + 20, /* macSize */ + 16, /* keySize */ + 0, /* ivSize */ + 1, /* blocksize */ + matrixCipher5Init, + matrixArc4, + matrixArc4, + NULL, + matrixRsaDecryptPub, + matrixRsaEncryptPub, + matrixRsaDecryptPriv, + sha1GenerateMac, + sha1VerifyMac}, +#endif /* USE_SSL_RSA_WITH_RC4_128_SHA */ +#ifdef USE_SSL_RSA_WITH_RC4_128_MD5 + {SSL_RSA_WITH_RC4_128_MD5, + 16, /* macSize */ + 16, /* keySize */ + 0, /* ivSize */ + 1, /* blocksize */ + matrixCipher4Init, + matrixArc4, + matrixArc4, + NULL, + matrixRsaDecryptPub, + matrixRsaEncryptPub, + matrixRsaDecryptPriv, + md5GenerateMac, + md5VerifyMac}, +#endif /* USE_SSL_RSA_WITH_RC4_128_MD5 */ +/* + These two USE_SSL_RSA_WITH_NULL ciphers are not recommended for use + in production applications. +*/ +#ifdef USE_SSL_RSA_WITH_NULL_MD5 + {SSL_RSA_WITH_NULL_MD5, + 16, /* macSize */ + 0, /* keySize */ + 0, /* ivSize */ + 0, /* blocksize */ + nullInit, + nullEncrypt, + nullDecrypt, + matrixRsaEncryptPriv, + matrixRsaDecryptPub, + matrixRsaEncryptPub, + matrixRsaDecryptPriv, + md5GenerateMac, + md5VerifyMac}, +#endif /* USE_SSL_RSA_WITH_NULL_MD5 */ +#ifdef USE_SSL_RSA_WITH_NULL_SHA + {SSL_RSA_WITH_NULL_SHA, + 20, /* macSize */ + 0, /* keySize */ + 0, /* ivSize */ + 0, /* blocksize */ + nullInit, + nullEncrypt, + nullDecrypt, + matrixRsaEncryptPriv, + matrixRsaDecryptPub, + matrixRsaEncryptPub, + matrixRsaDecryptPriv, + sha1GenerateMac, + sha1VerifyMac}, +#endif /* USE_SSL_RSA_WITH_NULL_SHA */ +/* + The NULL Cipher suite must exist and be the last in this list +*/ + {SSL_NULL_WITH_NULL_NULL, + 0, + 0, + 0, + 0, + nullInit, + nullEncrypt, + nullDecrypt, + nullEncryptPub, + nullDecryptPriv, + nullEncryptPub, + nullDecryptPriv, + nullGenerateMac, + nullVerifyMac} +}; + +/******************************************************************************/ +/* + Lookup the given cipher spec ID and return a pointer to the structure + if found. This is used when negotiating security, to find out what suites + we support. +*/ +sslCipherSpec_t *sslGetCipherSpec(int32 id) +{ + int32 i; + + i = 0; + do { + if ((int32)supportedCiphers[i].id == id) { + return &supportedCiphers[i]; + } + } while (supportedCiphers[i++].id != SSL_NULL_WITH_NULL_NULL) ; + + return NULL; +} + +/******************************************************************************/ +/* + Write out a list of the supported cipher suites to the caller's buffer + First 2 bytes are the number of cipher suite bytes, the remaining bytes are + the cipher suites, as two byte, network byte order values. +*/ +int32 sslGetCipherSpecList(unsigned char *c, int32 len) +{ + unsigned char *end, *p; + unsigned short i; + + if (len < 4) { + return -1; + } + end = c + len; + p = c; c += 2; + for (i = 0; supportedCiphers[i].id != SSL_NULL_WITH_NULL_NULL; i++) { + if (end - c < 2) { + return -1; + } + *c = (unsigned char)((supportedCiphers[i].id & 0xFF00) >> 8); c++; + *c = (unsigned char)(supportedCiphers[i].id & 0xFF); c++; + } + i *= 2; + *p = (unsigned char)(i >> 8); p++; + *p = (unsigned char)(i & 0xFF); + return i + 2; +} + +/******************************************************************************/ +/* + Return the length of the cipher spec list, including initial length bytes +*/ +int32 sslGetCipherSpecListLen(void) +{ + int32 i; + + for (i = 0; supportedCiphers[i].id != SSL_NULL_WITH_NULL_NULL; i++) { + } + return (i * 2) + 2; +} + + +/******************************************************************************/ +/* +*/ +#ifdef USE_SHA1_MAC +static int32 sha1GenerateMac(void *sslv, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac) +{ + ssl_t *ssl = (ssl_t*)sslv; + return ssl3HMACSha1(ssl->sec.writeMAC, ssl->sec.seq, type, data, len, mac); +} + +static int32 sha1VerifyMac(void *sslv, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac) +{ + ssl_t *ssl = (ssl_t*)sslv; + unsigned char buf[SSL_SHA1_HASH_SIZE]; + + ssl3HMACSha1(ssl->sec.readMAC, ssl->sec.remSeq, type, data, len, buf); + if (memcmp(buf, mac, SSL_SHA1_HASH_SIZE) == 0) { + return 0; + } + return -1; +} +#endif /* USE_SHA1_MAC */ + +/******************************************************************************/ +/* +*/ +#ifdef USE_MD5_MAC +static int32 md5GenerateMac(void *sslv, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac) +{ + ssl_t *ssl = (ssl_t*)sslv; + return ssl3HMACMd5(ssl->sec.writeMAC, ssl->sec.seq, type, data, len, mac); +} + +static int32 md5VerifyMac(void *sslv, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac) +{ + ssl_t *ssl = (ssl_t*)sslv; + unsigned char buf[SSL_MD5_HASH_SIZE]; + + ssl3HMACMd5(ssl->sec.readMAC, ssl->sec.remSeq, type, data, len, buf); + if (memcmp(buf, mac, SSL_MD5_HASH_SIZE) == 0) { + return 0; + } + return -1; +} + +#endif /* USE_MD5_MAC */ + +/******************************************************************************/ +/* + SSL_RSA_WITH_RC4_128_SHA cipher init +*/ +#ifdef USE_SSL_RSA_WITH_RC4_128_MD5 +static int32 matrixCipher4Init(sslSec_t *sec, int32 type) +{ + if (type == INIT_ENCRYPT_CIPHER) { + matrixArc4Init(&(sec->encryptCtx), sec->writeKey, 16); + } else { + matrixArc4Init(&(sec->decryptCtx), sec->readKey, 16); + } + + return 0; +} +#endif /* USE_SSL_RSA_WITH_RC4_128_MD5 */ + +/******************************************************************************/ +/* + SSL_RSA_WITH_RC4_128_SHA cipher init +*/ +#ifdef USE_SSL_RSA_WITH_RC4_128_SHA +static int32 matrixCipher5Init(sslSec_t *sec, int32 type) +{ + if (type == INIT_ENCRYPT_CIPHER) { + matrixArc4Init(&(sec->encryptCtx), sec->writeKey, 16); + } else { + matrixArc4Init(&(sec->decryptCtx), sec->readKey, 16); + } + + return 0; +} +#endif /* USE_SSL_RSA_WITH_RC4_128_SHA */ + +/******************************************************************************/ +/* + SSL_RSA_WITH_3DES_EDE_CBC_SHA cipher init +*/ +#ifdef USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA +static int32 matrixCipherAInit(sslSec_t *sec, int32 type) +{ + if (type == INIT_ENCRYPT_CIPHER) { + if (matrix3desInit(&(sec->encryptCtx), sec->writeIV, sec->writeKey, + SSL_DES3_KEY_LEN) < 0) { + return -1; + } + } else { + if (matrix3desInit(&(sec->decryptCtx), sec->readIV, sec->readKey, + SSL_DES3_KEY_LEN) < 0) { + return -1; + } + } + return 0; +} +#endif /* USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA */ + + +/******************************************************************************/ +/* + SSL_NULL_WITH_NULL_NULL cipher functions + Used in handshaking before SSL_RECORD_TYPE_CHANGE_CIPHER_SPEC message + FUTURE - remove the memcpy to support in-situ decryption +*/ +static int32 nullInit(sslSec_t *sec, int32 type) +{ + return 0; +} + +static int32 nullEncrypt(sslCipherContext_t *ctx, unsigned char *in, + unsigned char *out, int32 len) +{ + if (out != in) { + memcpy(out, in, len); + } + return len; +} + +static int32 nullDecrypt(sslCipherContext_t *ctx, unsigned char *in, + unsigned char *out, int32 len) +{ + if (out != in) { + memcpy(out, in, len); + } + return len; +} + +/* + FUTURE - remove both apis below +*/ +static int32 nullEncryptPub(psPool_t *pool, sslRsaKey_t *key, + unsigned char *in, int32 inlen, + unsigned char *out, int32 outlen) +{ + if (inlen <= outlen) { + matrixStrDebugMsg("Error: output buffer too small for NULL encrypt\n", + NULL); + return -1; + } + memcpy(out, in, inlen); + return inlen; +} + +static int32 nullDecryptPriv(psPool_t *pool, sslRsaKey_t *key, + unsigned char *in, int32 inlen, + unsigned char *out, int32 outlen) +{ + if (inlen <= outlen) { + matrixStrDebugMsg("Error: output buffer too small for NULL decrypt\n", + NULL); + return -1; + } + memcpy(out, in, inlen); + return inlen; +} + +static int32 nullGenerateMac(void *ssl, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac) +{ + return 0; +} + +static int32 nullVerifyMac(void *ssl, unsigned char type, unsigned char *data, + int32 len, unsigned char *mac) +{ + return 0; +} + + + +/******************************************************************************/ |