Ejemplo n.º 1
0
int ssl_derive_keys(ssl_context * ssl)
{
	size_t i;
	md5_context md5;
	sha1_context sha1;
	uint8_t tmp[64];
	uint8_t padding[16];
	uint8_t sha1sum[20];
	uint8_t keyblk[256];
	uint8_t *key1;
	uint8_t *key2;

	SSL_DEBUG_MSG(2, ("=> derive keys"));

	/*
	 * SSLv3:
	 *   master =
	 *     MD5( premaster + SHA1( 'A'   + premaster + randbytes ) ) +
	 *     MD5( premaster + SHA1( 'BB'  + premaster + randbytes ) ) +
	 *     MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
	 *
	 * TLSv1:
	 *   master = PRF( premaster, "master secret", randbytes )[0..47]
	 */
	if (ssl->resume == 0) {
		size_t len = ssl->pmslen;

		SSL_DEBUG_BUF(3, "premaster secret", ssl->premaster, len);

		if (ssl->minor_ver == SSL_MINOR_VERSION_0) {
			for (i = 0; i < 3; i++) {
				memset(padding, 'A' + i, 1 + i);

				sha1_starts(&sha1);
				sha1_update(&sha1, padding, 1 + i);
				sha1_update(&sha1, ssl->premaster, len);
				sha1_update(&sha1, ssl->randbytes, 64);
				sha1_finish(&sha1, sha1sum);

				md5_starts(&md5);
				md5_update(&md5, ssl->premaster, len);
				md5_update(&md5, sha1sum, 20);
				md5_finish(&md5, ssl->session->master + i * 16);
			}
		} else
			tls1_prf(ssl->premaster, len, "master secret",
				 ssl->randbytes, 64, ssl->session->master, 48);

		memset(ssl->premaster, 0, sizeof(ssl->premaster));
	} else
		SSL_DEBUG_MSG(3, ("no premaster (session resumed)"));

	/*
	 * Swap the client and server random values.
	 */
	memcpy(tmp, ssl->randbytes, 64);
	memcpy(ssl->randbytes, tmp + 32, 32);
	memcpy(ssl->randbytes + 32, tmp, 32);
	memset(tmp, 0, sizeof(tmp));

	/*
	 *  SSLv3:
	 *    key block =
	 *      MD5( master + SHA1( 'A'    + master + randbytes ) ) +
	 *      MD5( master + SHA1( 'BB'   + master + randbytes ) ) +
	 *      MD5( master + SHA1( 'CCC'  + master + randbytes ) ) +
	 *      MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
	 *      ...
	 *
	 *  TLSv1:
	 *    key block = PRF( master, "key expansion", randbytes )
	 */
	if (ssl->minor_ver == SSL_MINOR_VERSION_0) {
		for (i = 0; i < 16; i++) {
			memset(padding, 'A' + i, 1 + i);

			sha1_starts(&sha1);
			sha1_update(&sha1, padding, 1 + i);
			sha1_update(&sha1, ssl->session->master, 48);
			sha1_update(&sha1, ssl->randbytes, 64);
			sha1_finish(&sha1, sha1sum);

			md5_starts(&md5);
			md5_update(&md5, ssl->session->master, 48);
			md5_update(&md5, sha1sum, 20);
			md5_finish(&md5, keyblk + i * 16);
		}

		memset(&md5, 0, sizeof(md5));
		memset(&sha1, 0, sizeof(sha1));

		memset(padding, 0, sizeof(padding));
		memset(sha1sum, 0, sizeof(sha1sum));
	} else
		tls1_prf(ssl->session->master, 48, "key expansion",
			 ssl->randbytes, 64, keyblk, 256);

	SSL_DEBUG_MSG(3, ("cipher = %s", ssl_get_cipher(ssl)));
	SSL_DEBUG_BUF(3, "master secret", ssl->session->master, 48);
	SSL_DEBUG_BUF(4, "random bytes", ssl->randbytes, 64);
	SSL_DEBUG_BUF(4, "key block", keyblk, 256);

	memset(ssl->randbytes, 0, sizeof(ssl->randbytes));

	/*
	 * Determine the appropriate key, IV and MAC length.
	 */
	switch (ssl->session->cipher) {
#if defined(TROPICSSL_ARC4)
	case TLS_RSA_WITH_RC4_128_MD5:
		ssl->keylen = 16;
		ssl->minlen = 16;
		ssl->ivlen = 0;
		ssl->maclen = 16;
		break;

	case TLS_RSA_WITH_RC4_128_SHA:
		ssl->keylen = 16;
		ssl->minlen = 20;
		ssl->ivlen = 0;
		ssl->maclen = 20;
		break;
#endif

#if defined(TROPICSSL_DES)
	case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
	case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
		ssl->keylen = 24;
		ssl->minlen = 24;
		ssl->ivlen = 8;
		ssl->maclen = 20;
		break;
#endif

#if defined(TROPICSSL_AES)
	case TLS_RSA_WITH_AES_128_CBC_SHA:
		ssl->keylen = 16;
		ssl->minlen = 32;
		ssl->ivlen = 16;
		ssl->maclen = 20;
		break;

	case TLS_RSA_WITH_AES_256_CBC_SHA:
	case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
		ssl->keylen = 32;
		ssl->minlen = 32;
		ssl->ivlen = 16;
		ssl->maclen = 20;
		break;
#endif

#if defined(TROPICSSL_CAMELLIA)
	case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
		ssl->keylen = 16;
		ssl->minlen = 32;
		ssl->ivlen = 16;
		ssl->maclen = 20;
		break;

	case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
	case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
		ssl->keylen = 32;
		ssl->minlen = 32;
		ssl->ivlen = 16;
		ssl->maclen = 20;
		break;
#endif

	default:
		SSL_DEBUG_MSG(1, ("cipher %s is not available",
				  ssl_get_cipher(ssl)));
		return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE);
	}

	SSL_DEBUG_MSG(3, ("keylen: %d, minlen: %d, ivlen: %d, maclen: %d",
			  ssl->keylen, ssl->minlen, ssl->ivlen, ssl->maclen));

	/*
	 * Finally setup the cipher contexts, IVs and MAC secrets.
	 */
	if (ssl->endpoint == SSL_IS_CLIENT) {
		key1 = keyblk + ssl->maclen * 2;
		key2 = keyblk + ssl->maclen * 2 + ssl->keylen;

		memcpy(ssl->mac_enc, keyblk, ssl->maclen);
		memcpy(ssl->mac_dec, keyblk + ssl->maclen, ssl->maclen);

		memcpy(ssl->iv_enc, key2 + ssl->keylen, ssl->ivlen);
		memcpy(ssl->iv_dec, key2 + ssl->keylen + ssl->ivlen,
		       ssl->ivlen);
	} else {
		key1 = keyblk + ssl->maclen * 2 + ssl->keylen;
		key2 = keyblk + ssl->maclen * 2;

		memcpy(ssl->mac_dec, keyblk, ssl->maclen);
		memcpy(ssl->mac_enc, keyblk + ssl->maclen, ssl->maclen);

		memcpy(ssl->iv_dec, key1 + ssl->keylen, ssl->ivlen);
		memcpy(ssl->iv_enc, key1 + ssl->keylen + ssl->ivlen,
		       ssl->ivlen);
	}

	switch (ssl->session->cipher) {
#if defined(TROPICSSL_ARC4)
	case TLS_RSA_WITH_RC4_128_MD5:
	case TLS_RSA_WITH_RC4_128_SHA:
		arc4_setup((arc4_context *) ssl->ctx_enc, key1, ssl->keylen);
		arc4_setup((arc4_context *) ssl->ctx_dec, key2, ssl->keylen);
		break;
#endif

#if defined(TROPICSSL_DES)
	case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
	case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
		des3_set3key_enc((des3_context *) ssl->ctx_enc, key1);
		des3_set3key_dec((des3_context *) ssl->ctx_dec, key2);
		break;
#endif

#if defined(TROPICSSL_AES)
	case TLS_RSA_WITH_AES_128_CBC_SHA:
		aes_setkey_enc((aes_context *) ssl->ctx_enc, key1, 128);
		aes_setkey_dec((aes_context *) ssl->ctx_dec, key2, 128);
		break;

	case TLS_RSA_WITH_AES_256_CBC_SHA:
	case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
		aes_setkey_enc((aes_context *) ssl->ctx_enc, key1, 256);
		aes_setkey_dec((aes_context *) ssl->ctx_dec, key2, 256);
		break;
#endif

#if defined(TROPICSSL_CAMELLIA)
	case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
		camellia_setkey_enc((camellia_context *) ssl->ctx_enc, key1,
				    128);
		camellia_setkey_dec((camellia_context *) ssl->ctx_dec, key2,
				    128);
		break;

	case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
	case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
		camellia_setkey_enc((camellia_context *) ssl->ctx_enc, key1,
				    256);
		camellia_setkey_dec((camellia_context *) ssl->ctx_dec, key2,
				    256);
		break;
#endif

	default:
		return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE);
	}

	memset(keyblk, 0, sizeof(keyblk));

	SSL_DEBUG_MSG(2, ("<= derive keys"));

	return (0);
}
Ejemplo n.º 2
0
static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key,
                                     unsigned int key_length )
{
    return camellia_setkey_dec( (camellia_context *) ctx, key, key_length );
}