3 * Release $Name: MATRIXSSL_1_8_8_OPEN $
5 * Wrappers for the various cipher suites.
6 * Contributors should add additional cipher suites here.
7 * Enable specific suites at compile time in matrixConfig.h
10 * Copyright (c) PeerSec Networks, 2002-2009. All Rights Reserved.
11 * The latest version of this code is available at http://www.matrixssl.org
13 * This software is open source; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This General Public License does NOT permit incorporating this software
19 * into proprietary programs. If you are unable to comply with the GPL, a
20 * commercial license for this software may be purchased from PeerSec Networks
21 * at http://www.peersec.com
23 * This program is distributed in WITHOUT ANY WARRANTY; without even the
24 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
25 * See the GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 * http://www.gnu.org/copyleft/gpl.html
32 /******************************************************************************/
34 #include "matrixInternal.h"
36 /******************************************************************************/
38 Using void *ssl rather than ssl_t *ssl is a workaround for a chicken-egg
39 issue in matrixInternal.h where these function prototypes are used
40 before ssl_t is defined.
43 static int32
sha1GenerateMac(void *ssl
, unsigned char type
, unsigned char *data
,
44 int32 len
, unsigned char *mac
);
45 static int32
sha1VerifyMac(void *ssl
, unsigned char type
, unsigned char *data
,
46 int32 len
, unsigned char *mac
);
50 static int32
md5GenerateMac(void *ssl
, unsigned char type
, unsigned char *data
,
51 int32 len
, unsigned char *mac
);
52 static int32
md5VerifyMac(void *ssl
, unsigned char type
, unsigned char *data
,
53 int32 len
, unsigned char *mac
);
56 #ifdef USE_SSL_RSA_WITH_RC4_128_MD5
57 static int32
matrixCipher4Init(sslSec_t
*sec
, int32 type
);
58 #endif /* USE_SSL_RSA_WITH_RC4_128_MD5 */
60 #ifdef USE_SSL_RSA_WITH_RC4_128_SHA
61 static int32
matrixCipher5Init(sslSec_t
*sec
, int32 type
);
62 #endif /* USE_SSL_RSA_WITH_RC4_128_SHA */
64 #ifdef USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA
65 static int32
matrixCipherAInit(sslSec_t
*sec
, int32 type
);
66 #endif /* USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA */
71 static int32
nullInit(sslSec_t
*sec
, int32 type
);
72 static int32
nullEncrypt(sslCipherContext_t
*ctx
, unsigned char *in
,
73 unsigned char *out
, int32 len
);
74 static int32
nullDecrypt(sslCipherContext_t
*ctx
, unsigned char *in
,
75 unsigned char *out
, int32 len
);
76 static int32
nullEncryptPub(psPool_t
*pool
, sslRsaKey_t
*key
,
77 unsigned char *in
, int32 inlen
,
78 unsigned char *out
, int32 outlen
);
79 static int32
nullDecryptPriv(psPool_t
*pool
, sslRsaKey_t
*key
,
80 unsigned char *in
, int32 inlen
,
81 unsigned char *out
, int32 outlen
);
82 static int32
nullGenerateMac(void *ssl
, unsigned char type
, unsigned char *data
,
83 int32 len
, unsigned char *mac
);
84 static int32
nullVerifyMac(void *ssl
, unsigned char type
, unsigned char *data
,
85 int32 len
, unsigned char *mac
);
87 /******************************************************************************/
89 static sslCipherSpec_t supportedCiphers
[] = {
91 New ciphers should be added here, similar to the ones below
92 These ciphers should be in order of the most desireable to the
93 least desireable ciphers to negotiate.
95 #ifdef USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA
96 {SSL_RSA_WITH_3DES_EDE_CBC_SHA
,
107 matrixRsaDecryptPriv
,
110 #endif /* USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA */
111 #ifdef USE_SSL_RSA_WITH_RC4_128_SHA
112 {SSL_RSA_WITH_RC4_128_SHA
,
123 matrixRsaDecryptPriv
,
126 #endif /* USE_SSL_RSA_WITH_RC4_128_SHA */
127 #ifdef USE_SSL_RSA_WITH_RC4_128_MD5
128 {SSL_RSA_WITH_RC4_128_MD5
,
139 matrixRsaDecryptPriv
,
142 #endif /* USE_SSL_RSA_WITH_RC4_128_MD5 */
144 These two USE_SSL_RSA_WITH_NULL ciphers are not recommended for use
145 in production applications.
147 #ifdef USE_SSL_RSA_WITH_NULL_MD5
148 {SSL_RSA_WITH_NULL_MD5
,
156 matrixRsaEncryptPriv
,
159 matrixRsaDecryptPriv
,
162 #endif /* USE_SSL_RSA_WITH_NULL_MD5 */
163 #ifdef USE_SSL_RSA_WITH_NULL_SHA
164 {SSL_RSA_WITH_NULL_SHA
,
172 matrixRsaEncryptPriv
,
175 matrixRsaDecryptPriv
,
178 #endif /* USE_SSL_RSA_WITH_NULL_SHA */
180 The NULL Cipher suite must exist and be the last in this list
182 {SSL_NULL_WITH_NULL_NULL
,
198 /******************************************************************************/
200 Lookup the given cipher spec ID and return a pointer to the structure
201 if found. This is used when negotiating security, to find out what suites
204 sslCipherSpec_t
*sslGetCipherSpec(int32 id
)
210 if ((int32
)supportedCiphers
[i
].id
== id
) {
211 return &supportedCiphers
[i
];
213 } while (supportedCiphers
[i
++].id
!= SSL_NULL_WITH_NULL_NULL
) ;
218 /******************************************************************************/
220 Write out a list of the supported cipher suites to the caller's buffer
221 First 2 bytes are the number of cipher suite bytes, the remaining bytes are
222 the cipher suites, as two byte, network byte order values.
224 int32
sslGetCipherSpecList(unsigned char *c
, int32 len
)
226 unsigned char *end
, *p
;
234 for (i
= 0; supportedCiphers
[i
].id
!= SSL_NULL_WITH_NULL_NULL
; i
++) {
238 *c
= (unsigned char)((supportedCiphers
[i
].id
& 0xFF00) >> 8); c
++;
239 *c
= (unsigned char)(supportedCiphers
[i
].id
& 0xFF); c
++;
242 *p
= (unsigned char)(i
>> 8); p
++;
243 *p
= (unsigned char)(i
& 0xFF);
247 /******************************************************************************/
249 Return the length of the cipher spec list, including initial length bytes
251 int32
sslGetCipherSpecListLen(void)
255 for (i
= 0; supportedCiphers
[i
].id
!= SSL_NULL_WITH_NULL_NULL
; i
++) {
261 /******************************************************************************/
265 static int32
sha1GenerateMac(void *sslv
, unsigned char type
, unsigned char *data
,
266 int32 len
, unsigned char *mac
)
268 ssl_t
*ssl
= (ssl_t
*)sslv
;
269 return ssl3HMACSha1(ssl
->sec
.writeMAC
, ssl
->sec
.seq
, type
, data
, len
, mac
);
272 static int32
sha1VerifyMac(void *sslv
, unsigned char type
, unsigned char *data
,
273 int32 len
, unsigned char *mac
)
275 ssl_t
*ssl
= (ssl_t
*)sslv
;
276 unsigned char buf
[SSL_SHA1_HASH_SIZE
];
278 ssl3HMACSha1(ssl
->sec
.readMAC
, ssl
->sec
.remSeq
, type
, data
, len
, buf
);
279 if (memcmp(buf
, mac
, SSL_SHA1_HASH_SIZE
) == 0) {
284 #endif /* USE_SHA1_MAC */
286 /******************************************************************************/
290 static int32
md5GenerateMac(void *sslv
, unsigned char type
, unsigned char *data
,
291 int32 len
, unsigned char *mac
)
293 ssl_t
*ssl
= (ssl_t
*)sslv
;
294 return ssl3HMACMd5(ssl
->sec
.writeMAC
, ssl
->sec
.seq
, type
, data
, len
, mac
);
297 static int32
md5VerifyMac(void *sslv
, unsigned char type
, unsigned char *data
,
298 int32 len
, unsigned char *mac
)
300 ssl_t
*ssl
= (ssl_t
*)sslv
;
301 unsigned char buf
[SSL_MD5_HASH_SIZE
];
303 ssl3HMACMd5(ssl
->sec
.readMAC
, ssl
->sec
.remSeq
, type
, data
, len
, buf
);
304 if (memcmp(buf
, mac
, SSL_MD5_HASH_SIZE
) == 0) {
310 #endif /* USE_MD5_MAC */
312 /******************************************************************************/
314 SSL_RSA_WITH_RC4_128_SHA cipher init
316 #ifdef USE_SSL_RSA_WITH_RC4_128_MD5
317 static int32
matrixCipher4Init(sslSec_t
*sec
, int32 type
)
319 if (type
== INIT_ENCRYPT_CIPHER
) {
320 matrixArc4Init(&(sec
->encryptCtx
), sec
->writeKey
, 16);
322 matrixArc4Init(&(sec
->decryptCtx
), sec
->readKey
, 16);
327 #endif /* USE_SSL_RSA_WITH_RC4_128_MD5 */
329 /******************************************************************************/
331 SSL_RSA_WITH_RC4_128_SHA cipher init
333 #ifdef USE_SSL_RSA_WITH_RC4_128_SHA
334 static int32
matrixCipher5Init(sslSec_t
*sec
, int32 type
)
336 if (type
== INIT_ENCRYPT_CIPHER
) {
337 matrixArc4Init(&(sec
->encryptCtx
), sec
->writeKey
, 16);
339 matrixArc4Init(&(sec
->decryptCtx
), sec
->readKey
, 16);
344 #endif /* USE_SSL_RSA_WITH_RC4_128_SHA */
346 /******************************************************************************/
348 SSL_RSA_WITH_3DES_EDE_CBC_SHA cipher init
350 #ifdef USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA
351 static int32
matrixCipherAInit(sslSec_t
*sec
, int32 type
)
353 if (type
== INIT_ENCRYPT_CIPHER
) {
354 if (matrix3desInit(&(sec
->encryptCtx
), sec
->writeIV
, sec
->writeKey
,
355 SSL_DES3_KEY_LEN
) < 0) {
359 if (matrix3desInit(&(sec
->decryptCtx
), sec
->readIV
, sec
->readKey
,
360 SSL_DES3_KEY_LEN
) < 0) {
366 #endif /* USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA */
369 /******************************************************************************/
371 SSL_NULL_WITH_NULL_NULL cipher functions
372 Used in handshaking before SSL_RECORD_TYPE_CHANGE_CIPHER_SPEC message
373 FUTURE - remove the memcpy to support in-situ decryption
375 static int32
nullInit(sslSec_t
*sec
, int32 type
)
380 static int32
nullEncrypt(sslCipherContext_t
*ctx
, unsigned char *in
,
381 unsigned char *out
, int32 len
)
384 memcpy(out
, in
, len
);
389 static int32
nullDecrypt(sslCipherContext_t
*ctx
, unsigned char *in
,
390 unsigned char *out
, int32 len
)
393 memcpy(out
, in
, len
);
399 FUTURE - remove both apis below
401 static int32
nullEncryptPub(psPool_t
*pool
, sslRsaKey_t
*key
,
402 unsigned char *in
, int32 inlen
,
403 unsigned char *out
, int32 outlen
)
405 if (inlen
<= outlen
) {
406 matrixStrDebugMsg("Error: output buffer too small for NULL encrypt\n",
410 memcpy(out
, in
, inlen
);
414 static int32
nullDecryptPriv(psPool_t
*pool
, sslRsaKey_t
*key
,
415 unsigned char *in
, int32 inlen
,
416 unsigned char *out
, int32 outlen
)
418 if (inlen
<= outlen
) {
419 matrixStrDebugMsg("Error: output buffer too small for NULL decrypt\n",
423 memcpy(out
, in
, inlen
);
427 static int32
nullGenerateMac(void *ssl
, unsigned char type
, unsigned char *data
,
428 int32 len
, unsigned char *mac
)
433 static int32
nullVerifyMac(void *ssl
, unsigned char type
, unsigned char *data
,
434 int32 len
, unsigned char *mac
)
441 /******************************************************************************/