Exemplo n.º 1
0
int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
                               const char *label, size_t label_len,
                               const uint8_t *context, size_t context_len,
                               int use_context) {
  if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) {
    return 0;
  }

  /* Exporters may not be used in the middle of a renegotiation. */
  if (SSL_in_init(ssl) && !SSL_in_false_start(ssl)) {
    return 0;
  }

  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
    return tls13_export_keying_material(ssl, out, out_len, label, label_len,
                                        context, context_len, use_context);
  }

  size_t seed_len = 2 * SSL3_RANDOM_SIZE;
  if (use_context) {
    if (context_len >= 1u << 16) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
      return 0;
    }
    seed_len += 2 + context_len;
  }
  uint8_t *seed = OPENSSL_malloc(seed_len);
  if (seed == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return 0;
  }

  OPENSSL_memcpy(seed, ssl->s3->client_random, SSL3_RANDOM_SIZE);
  OPENSSL_memcpy(seed + SSL3_RANDOM_SIZE, ssl->s3->server_random,
                 SSL3_RANDOM_SIZE);
  if (use_context) {
    seed[2 * SSL3_RANDOM_SIZE] = (uint8_t)(context_len >> 8);
    seed[2 * SSL3_RANDOM_SIZE + 1] = (uint8_t)context_len;
    OPENSSL_memcpy(seed + 2 * SSL3_RANDOM_SIZE + 2, context, context_len);
  }

  const EVP_MD *digest = ssl_get_handshake_digest(
      SSL_get_session(ssl)->cipher->algorithm_prf, ssl3_protocol_version(ssl));
  if (digest == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }
  int ret = tls1_prf(digest, out, out_len, SSL_get_session(ssl)->master_key,
                     SSL_get_session(ssl)->master_key_length, label, label_len,
                     seed, seed_len, NULL, 0);
  OPENSSL_free(seed);
  return ret;
}
Exemplo n.º 2
0
int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out,
                                const uint8_t *premaster,
                                size_t premaster_len) {
  const SSL *ssl = hs->ssl;
  if (hs->extended_master_secret) {
    uint8_t digests[EVP_MAX_MD_SIZE];
    size_t digests_len;
    if (!SSL_TRANSCRIPT_get_hash(&hs->transcript, digests, &digests_len) ||
        !tls1_prf(SSL_TRANSCRIPT_md(&hs->transcript), out,
                  SSL3_MASTER_SECRET_SIZE, premaster, premaster_len,
                  TLS_MD_EXTENDED_MASTER_SECRET_CONST,
                  TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests,
                  digests_len, NULL, 0)) {
      return 0;
    }
  } else {
    if (ssl3_protocol_version(ssl) == SSL3_VERSION) {
      if (!ssl3_prf(out, SSL3_MASTER_SECRET_SIZE, premaster, premaster_len,
                    TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE,
                    ssl->s3->client_random, SSL3_RANDOM_SIZE,
                    ssl->s3->server_random, SSL3_RANDOM_SIZE)) {
        return 0;
      }
    } else {
      if (!tls1_prf(SSL_TRANSCRIPT_md(&hs->transcript), out,
                    SSL3_MASTER_SECRET_SIZE, premaster, premaster_len,
                    TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE,
                    ssl->s3->client_random, SSL3_RANDOM_SIZE,
                    ssl->s3->server_random, SSL3_RANDOM_SIZE)) {
        return 0;
      }
    }
  }

  return SSL3_MASTER_SECRET_SIZE;
}
Exemplo n.º 3
0
int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) {
  if (ssl3_protocol_version(ssl) == SSL3_VERSION) {
    return ssl3_prf(out, out_len, SSL_get_session(ssl)->master_key,
                    SSL_get_session(ssl)->master_key_length,
                    TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
                    ssl->s3->server_random, SSL3_RANDOM_SIZE,
                    ssl->s3->client_random, SSL3_RANDOM_SIZE);
  }

  const EVP_MD *digest = ssl_get_handshake_digest(
      SSL_get_session(ssl)->cipher->algorithm_prf, ssl3_protocol_version(ssl));
  if (digest == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }
  return tls1_prf(digest, out, out_len, SSL_get_session(ssl)->master_key,
                  SSL_get_session(ssl)->master_key_length,
                  TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
                  ssl->s3->server_random, SSL3_RANDOM_SIZE,
                  ssl->s3->client_random, SSL3_RANDOM_SIZE);
}
Exemplo n.º 4
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);
}