Exemplo n.º 1
0
/* Cipher Suite's functions */
const cipher_entry_st *_gnutls_cipher_suite_get_cipher_algo(const uint8_t
							    suite[2])
{
	int ret = 0;
	CIPHER_SUITE_ALG_LOOP(ret = p->block_algorithm);
	return cipher_to_entry(ret);
}
Exemplo n.º 2
0
int
_gnutls_decrypt_pbes1_des_md5_data(const char *password,
			   unsigned password_len,
			   const struct pbkdf2_params *kdf_params,
			   const struct pbe_enc_params *enc_params,
			   gnutls_datum_t *encrypted_data, /* we re-use it */
			   gnutls_datum_t *decrypted_data)
{
	int result;
	gnutls_datum_t dkey, d_iv;
	cipher_hd_st ch;
	uint8_t key[16];
	const unsigned block_size = 8;

	if (enc_params->cipher != GNUTLS_CIPHER_DES_CBC)
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

	if (encrypted_data->size % block_size != 0)
		return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);

	/* generate the key
	 */
	pbkdf1_md5(password, password_len, kdf_params->salt, kdf_params->iter_count, sizeof(key), key);

	dkey.data = key;
	dkey.size = 8;
	d_iv.data = &key[8];
	d_iv.size = 8;
	result =
	    _gnutls_cipher_init(&ch, cipher_to_entry(GNUTLS_CIPHER_DES_CBC),
				&dkey, &d_iv, 0);
	if (result < 0)
		return gnutls_assert_val(result);

	result = _gnutls_cipher_decrypt(&ch, encrypted_data->data, encrypted_data->size);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	if ((int)encrypted_data->size - encrypted_data->data[encrypted_data->size - 1] < 0) {
		gnutls_assert();
		result = GNUTLS_E_ILLEGAL_PARAMETER;
		goto error;
	}

	decrypted_data->data = encrypted_data->data;
	decrypted_data->size = encrypted_data->size - encrypted_data->data[encrypted_data->size - 1];

	result = 0;
 error:
	_gnutls_cipher_deinit(&ch);

	return result;
}
Exemplo n.º 3
0
void
_gnutls_epoch_set_null_algos(gnutls_session_t session,
			     record_parameters_st * params)
{
	/* This is only called on startup. We are extra paranoid about this
	   because it may cause unencrypted application data to go out on
	   the wire. */
	if (params->initialized || params->epoch != 0) {
		gnutls_assert();
		return;
	}

	params->cipher = cipher_to_entry(GNUTLS_CIPHER_NULL);
	params->mac = mac_to_entry(GNUTLS_MAC_NULL);
	params->compression_algorithm = GNUTLS_COMP_NULL;
	params->initialized = 1;
}
Exemplo n.º 4
0
int
_gnutls_epoch_set_cipher_suite(gnutls_session_t session,
			       int epoch_rel, const uint8_t suite[2])
{
	const cipher_entry_st *cipher_algo;
	const mac_entry_st *mac_algo;
	record_parameters_st *params;
	const gnutls_cipher_suite_entry_st *cs;
	int ret;

	ret = _gnutls_epoch_get(session, epoch_rel, &params);
	if (ret < 0)
		return gnutls_assert_val(ret);

	if (params->initialized
	    || params->cipher != NULL || params->mac != NULL)
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

	cs = ciphersuite_to_entry(suite);
	if (cs == NULL)
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

	cipher_algo = cipher_to_entry(cs->block_algorithm);
	mac_algo = mac_to_entry(cs->mac_algorithm);

	if (_gnutls_cipher_is_ok(cipher_algo) == 0
	    || _gnutls_mac_is_ok(mac_algo) == 0)
		return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);

	if (_gnutls_cipher_priority(session, cipher_algo->id) < 0)
		return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);

	if (_gnutls_mac_priority(session, mac_algo->id) < 0)
		return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);

	params->cipher = cipher_algo;
	params->mac = mac_algo;

	return 0;
}
Exemplo n.º 5
0
int
_gnutls_encrypt_session_ticket(gnutls_session_t session,
			       const gnutls_datum_t *state,
			       gnutls_datum_t *ticket_data)
{
	cipher_hd_st cipher_hd;
	gnutls_datum_t IV;
	gnutls_datum_t encrypted_state = {NULL,0};
	uint8_t iv[TICKET_IV_SIZE];
	gnutls_datum_t stek_cipher_key, stek_mac_key, stek_key_name;
	struct ticket_st ticket;
	int ret;

	encrypted_state.size = ((state->size + TICKET_BLOCK_SIZE - 1) / TICKET_BLOCK_SIZE) * TICKET_BLOCK_SIZE;
	ticket_data->size = TICKET_KEY_NAME_SIZE + TICKET_IV_SIZE + 2 +
	    encrypted_state.size + TICKET_MAC_SIZE;
	ticket_data->data = gnutls_calloc(1, ticket_data->size);
	if (!ticket_data->data) {
		gnutls_assert();
		ret = GNUTLS_E_MEMORY_ERROR;
		goto cleanup;
	}
	encrypted_state.data = ticket_data->data + TICKET_KEY_NAME_SIZE + TICKET_IV_SIZE + 2;
	memcpy(encrypted_state.data, state->data, state->size);

	/* Retrieve ticket encryption keys */
	if (_gnutls_get_session_ticket_encryption_key(session,
						      &stek_key_name,
						      &stek_mac_key,
						      &stek_cipher_key) < 0) {
		ret = GNUTLS_E_ENCRYPTION_FAILED;
		goto cleanup;
	}

	/* Encrypt state */
	IV.data = iv;
	IV.size = TICKET_IV_SIZE;

	ret = gnutls_rnd(GNUTLS_RND_NONCE, iv, TICKET_IV_SIZE);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_cipher_init(&cipher_hd,
				cipher_to_entry(TICKET_CIPHER),
				&stek_cipher_key, &IV, 1);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = _gnutls_cipher_encrypt(&cipher_hd, encrypted_state.data,
				     encrypted_state.size);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup2;
	}


	/* Fill the ticket structure to compute MAC. */
	memcpy(ticket.key_name, stek_key_name.data, stek_key_name.size);
	memcpy(ticket.IV, IV.data, IV.size);
	ticket.encrypted_state_len = encrypted_state.size;
	ticket.encrypted_state = encrypted_state.data;

	ret = digest_ticket(&stek_mac_key, &ticket, ticket.mac);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup2;
	}

	encrypted_state.data = NULL;

	pack_ticket(&ticket, ticket_data);

	ret = 0;

cleanup2:
	_gnutls_cipher_deinit(&cipher_hd);

cleanup:
	_gnutls_free_datum(&encrypted_state);

	return ret;
}
Exemplo n.º 6
0
int
_gnutls_decrypt_session_ticket(gnutls_session_t session,
			       const gnutls_datum_t *ticket_data,
			       gnutls_datum_t *state)
{
	cipher_hd_st cipher_hd;
	gnutls_datum_t IV;
	gnutls_datum_t stek_key_name, stek_cipher_key, stek_mac_key;
	uint8_t cmac[TICKET_MAC_SIZE];
	struct ticket_st ticket;
	int ret;

	/* callers must have that checked */
	assert(!(session->internals.flags & GNUTLS_NO_TICKETS));

	/* Retrieve ticket decryption keys */
	if (_gnutls_get_session_ticket_decryption_key(session,
						      ticket_data,
						      &stek_key_name,
						      &stek_mac_key,
						      &stek_cipher_key) < 0)
		return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);

	ret = unpack_ticket(ticket_data, &ticket);
	if (ret < 0)
		return ret;

	/* If the key name of the ticket does not match the one that is currently active,
	   issue a new ticket. */
	if (memcmp
	    (ticket.key_name, stek_key_name.data,
	     stek_key_name.size)) {
		ret = GNUTLS_E_DECRYPTION_FAILED;
		goto cleanup;
	}

	/* Check the integrity of ticket */
	ret = digest_ticket(&stek_mac_key, &ticket, cmac);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	if (memcmp(ticket.mac, cmac, TICKET_MAC_SIZE)) {
		ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
		goto cleanup;
	}

	if (ticket.encrypted_state_len % TICKET_BLOCK_SIZE != 0) {
		ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
		goto cleanup;
	}

	/* Decrypt encrypted_state */
	IV.data = ticket.IV;
	IV.size = TICKET_IV_SIZE;
	ret =
	    _gnutls_cipher_init(&cipher_hd,
				cipher_to_entry(TICKET_CIPHER),
				&stek_cipher_key, &IV, 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = _gnutls_cipher_decrypt(&cipher_hd, ticket.encrypted_state,
				     ticket.encrypted_state_len);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup2;
	}

	state->data = ticket.encrypted_state;
	state->size = ticket.encrypted_state_len;

	ticket.encrypted_state = NULL;

	ret = 0;

cleanup2:
	_gnutls_cipher_deinit(&cipher_hd);

cleanup:
	deinit_ticket(&ticket);

	return ret;

}
Exemplo n.º 7
0
static int
encrypt_ticket(gnutls_session_t session, session_ticket_ext_st * priv,
               struct ticket_st *ticket)
{
    cipher_hd_st cipher_hd;
    gnutls_datum_t key, IV;
    gnutls_datum_t state = {NULL,0}, encrypted_state = {NULL,0};
    uint8_t iv[IV_SIZE];
    gnutls_datum_t mac_secret;
    uint32_t t;
    int ret;

    /* Pack security parameters. */
    ret = _gnutls_session_pack(session, &state);
    if (ret < 0) {
        gnutls_assert();
        return ret;
    }

    encrypted_state.size = ((state.size + BLOCK_SIZE - 1) / BLOCK_SIZE) * BLOCK_SIZE;
    encrypted_state.data = gnutls_calloc(1, encrypted_state.size);
    if (!encrypted_state.data) {
        gnutls_assert();
        ret = GNUTLS_E_MEMORY_ERROR;
        goto cleanup;
    }
    memcpy(encrypted_state.data, state.data, state.size);

    /* Encrypt state */
    key.data = (void *) &priv->key[KEY_POS];
    key.size = CIPHER_KEY_SIZE;
    IV.data = iv;
    IV.size = IV_SIZE;

    t = gnutls_time(0);
    memcpy(iv, &t, 4);
    ret = gnutls_rnd(GNUTLS_RND_NONCE, iv+4, IV_SIZE-4);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_cipher_init(&cipher_hd,
                            cipher_to_entry(CIPHER),
                            &key, &IV, 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret = _gnutls_cipher_encrypt(&cipher_hd, encrypted_state.data,
                                 encrypted_state.size);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup2;
    }


    /* Fill the ticket structure to compute MAC. */
    memcpy(ticket->key_name, &priv->key[NAME_POS], KEY_NAME_SIZE);
    memcpy(ticket->IV, IV.data, IV.size);
    ticket->encrypted_state_len = encrypted_state.size;
    ticket->encrypted_state = encrypted_state.data;

    mac_secret.data = &priv->key[MAC_SECRET_POS];
    mac_secret.size = MAC_SECRET_SIZE;
    ret = digest_ticket(&mac_secret, ticket, ticket->mac);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup2;
    }

    encrypted_state.data = NULL;

    ret = 0;

cleanup2:
    _gnutls_cipher_deinit(&cipher_hd);

cleanup:
    _gnutls_free_datum(&state);
    _gnutls_free_datum(&encrypted_state);

    return ret;
}
Exemplo n.º 8
0
static int
decrypt_ticket(gnutls_session_t session, session_ticket_ext_st * priv,
               struct ticket_st *ticket)
{
    cipher_hd_st cipher_hd;
    gnutls_datum_t key, IV, state, mac_secret;
    uint8_t cmac[MAC_SIZE];
    time_t timestamp = gnutls_time(0);
    int ret;

    /* Check the integrity of ticket */
    mac_secret.data = (void *) &priv->key[MAC_SECRET_POS];
    mac_secret.size = MAC_SECRET_SIZE;
    ret = digest_ticket(&mac_secret, ticket, cmac);
    if (ret < 0)
        return gnutls_assert_val(ret);

    if (memcmp(ticket->mac, cmac, MAC_SIZE))
        return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);

    if (ticket->encrypted_state_len % BLOCK_SIZE != 0)
        return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);

    /* Decrypt encrypted_state */
    key.data = (void *) &priv->key[KEY_POS];
    key.size = CIPHER_KEY_SIZE;
    IV.data = ticket->IV;
    IV.size = IV_SIZE;
    ret =
        _gnutls_cipher_init(&cipher_hd,
                            cipher_to_entry(CIPHER),
                            &key, &IV, 0);
    if (ret < 0) {
        gnutls_assert();
        return ret;
    }
    ret = _gnutls_cipher_decrypt(&cipher_hd, ticket->encrypted_state,
                                 ticket->encrypted_state_len);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    /* Unpack security parameters. */
    state.data = ticket->encrypted_state;
    state.size = ticket->encrypted_state_len;
    ret = _gnutls_session_unpack(session, &state);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    if (timestamp -
            session->internals.resumed_security_parameters.timestamp >
            session->internals.expire_time
            || session->internals.resumed_security_parameters.timestamp >
            timestamp) {
        gnutls_assert();
        ret = GNUTLS_E_EXPIRED;
        goto cleanup;
    }

    ret = _gnutls_check_resumed_params(session);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    session->internals.resumed = RESUME_TRUE;

    ret = 0;
cleanup:
    _gnutls_cipher_deinit(&cipher_hd);

    return ret;

}