static int _gnutls_check_algos (gnutls_session_t session, const uint8_t suite[2], gnutls_compression_method_t comp_algo) { gnutls_cipher_algorithm_t cipher_algo; gnutls_mac_algorithm_t mac_algo; cipher_algo = _gnutls_cipher_suite_get_cipher_algo (suite); mac_algo = _gnutls_cipher_suite_get_mac_algo (suite); if (_gnutls_cipher_is_ok (cipher_algo) != 0) return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR); if (_gnutls_cipher_priority (session, cipher_algo) < 0) return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM); if (_gnutls_mac_is_ok (mac_algo) != 0) return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR); if (_gnutls_mac_priority (session, mac_algo) < 0) return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM); if (_gnutls_compression_is_ok (comp_algo) != 0) return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM); return 0; }
int _gnutls_epoch_set_compression(gnutls_session_t session, int epoch_rel, gnutls_compression_method_t comp_algo) { record_parameters_st *params; int ret; ret = _gnutls_epoch_get(session, epoch_rel, ¶ms); if (ret < 0) return gnutls_assert_val(ret); if (params->initialized || params->compression_algorithm != GNUTLS_COMP_UNKNOWN) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); if (_gnutls_compression_is_ok(comp_algo) != 0) return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM); params->compression_algorithm = comp_algo; return 0; }
int _gnutls_epoch_set_keys (gnutls_session_t session, uint16_t epoch) { int hash_size; int IV_size; int key_size, export_flag; gnutls_cipher_algorithm_t cipher_algo; gnutls_mac_algorithm_t mac_algo; gnutls_compression_method_t comp_algo; record_parameters_st *params; int ret; gnutls_protocol_t ver = gnutls_protocol_get_version (session); ret = _gnutls_epoch_get (session, epoch, ¶ms); if (ret < 0) return gnutls_assert_val (ret); if (params->initialized) return 0; _gnutls_record_log ("REC[%p]: Initializing epoch #%u\n", session, params->epoch); cipher_algo = params->cipher_algorithm; mac_algo = params->mac_algorithm; comp_algo = params->compression_algorithm; if (_gnutls_cipher_is_ok (cipher_algo) != 0 || _gnutls_mac_is_ok (mac_algo) != 0) return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR); if (_gnutls_compression_is_ok (comp_algo) != 0) return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM); IV_size = _gnutls_cipher_get_iv_size (cipher_algo); key_size = gnutls_cipher_get_key_size (cipher_algo); export_flag = _gnutls_cipher_get_export_flag (cipher_algo); hash_size = _gnutls_hmac_get_algo_len (mac_algo); ret = _gnutls_set_keys (session, params, hash_size, IV_size, key_size, export_flag); if (ret < 0) return gnutls_assert_val (ret); ret = _gnutls_init_record_state (params, ver, 1, ¶ms->read); if (ret < 0) return gnutls_assert_val (ret); ret = _gnutls_init_record_state (params, ver, 0, ¶ms->write); if (ret < 0) return gnutls_assert_val (ret); params->record_sw_size = 0; _gnutls_record_log ("REC[%p]: Epoch #%u ready\n", session, params->epoch); params->initialized = 1; return 0; }
int _gnutls_set_write_compression (gnutls_session_t session, gnutls_compression_method_t algo) { if (_gnutls_compression_is_ok (algo) == 0) { session->security_parameters.write_compression_algorithm = algo; } else { gnutls_assert (); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } return 0; }
/* Initializes the write connection session * (write encrypted data) */ int _gnutls_write_connection_state_init (gnutls_session_t session) { int mac_size; int rc; _gnutls_uint64zero (session->connection_state.write_sequence_number); /* Update internals from CipherSuite selected. * If we are resuming just copy the connection session */ if (session->internals.resumed == RESUME_FALSE) { rc = _gnutls_set_write_cipher (session, _gnutls_cipher_suite_get_cipher_algo (&session->security_parameters. current_cipher_suite)); if (rc < 0) return rc; rc = _gnutls_set_write_mac (session, _gnutls_cipher_suite_get_mac_algo (&session->security_parameters. current_cipher_suite)); if (rc < 0) return rc; rc = _gnutls_set_kx (session, _gnutls_cipher_suite_get_kx_algo (&session->security_parameters. current_cipher_suite)); if (rc < 0) return rc; rc = _gnutls_set_write_compression (session, session->internals. compression_method); if (rc < 0) return rc; } else { /* RESUME_TRUE */ _gnutls_cpy_write_security_parameters (&session-> security_parameters, &session-> internals. resumed_security_parameters); } rc = _gnutls_set_write_keys (session); if (rc < 0) return rc; _gnutls_handshake_log ("HSK[%x]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name (&session-> security_parameters. current_cipher_suite)); if (_gnutls_compression_is_ok (session->security_parameters.write_compression_algorithm) != 0) { gnutls_assert (); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } if (_gnutls_mac_is_ok (session->security_parameters.write_mac_algorithm) != 0) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } /* Free all the previous keys/ sessions etc. */ if (session->connection_state.write_mac_secret.data != NULL) _gnutls_free_datum (&session->connection_state.write_mac_secret); if (session->connection_state.write_cipher_state != NULL) _gnutls_cipher_deinit (session->connection_state.write_cipher_state); if (session->connection_state.write_compression_state != NULL) _gnutls_comp_deinit (session->connection_state. write_compression_state, 0); mac_size = _gnutls_hash_get_algo_len (session->security_parameters. write_mac_algorithm); _gnutls_handshake_log ("HSK[%x]: Initializing internal [write] cipher sessions\n", session); switch (session->security_parameters.entity) { case GNUTLS_SERVER: /* initialize cipher session */ session->connection_state.write_cipher_state = _gnutls_cipher_init (session->security_parameters. write_bulk_cipher_algorithm, &session->cipher_specs. server_write_key, &session->cipher_specs.server_write_IV); if (session->connection_state.write_cipher_state == GNUTLS_CIPHER_FAILED && session->security_parameters. write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } /* copy mac secrets from cipherspecs, to connection * session. */ if (mac_size > 0) { if (_gnutls_sset_datum (&session->connection_state. write_mac_secret, session->cipher_specs. server_write_mac_secret.data, session->cipher_specs. server_write_mac_secret.size) < 0) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } } break; case GNUTLS_CLIENT: session->connection_state.write_cipher_state = _gnutls_cipher_init (session->security_parameters. write_bulk_cipher_algorithm, &session->cipher_specs. client_write_key, &session->cipher_specs.client_write_IV); if (session->connection_state.write_cipher_state == GNUTLS_CIPHER_FAILED && session->security_parameters. write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } /* copy mac secret to connection session */ if (mac_size > 0) { if (_gnutls_sset_datum (&session->connection_state. write_mac_secret, session->cipher_specs. client_write_mac_secret.data, session->cipher_specs. client_write_mac_secret.size) < 0) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } } break; default: gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } session->connection_state.write_compression_state = _gnutls_comp_init (session->security_parameters. write_compression_algorithm, 0); if (session->connection_state.write_compression_state == GNUTLS_COMP_FAILED) { gnutls_assert (); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } return 0; }
int _gnutls_epoch_set_keys(gnutls_session_t session, uint16_t epoch) { int hash_size; int IV_size; int key_size; gnutls_compression_method_t comp_algo; record_parameters_st *params; int ret; const version_entry_st *ver = get_version(session); if (unlikely(ver == NULL)) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); ret = _gnutls_epoch_get(session, epoch, ¶ms); if (ret < 0) return gnutls_assert_val(ret); if (params->initialized) return 0; _gnutls_record_log ("REC[%p]: Initializing epoch #%u\n", session, params->epoch); comp_algo = params->compression_algorithm; if (_gnutls_cipher_is_ok(params->cipher) == 0 || _gnutls_mac_is_ok(params->mac) == 0) return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); if (_gnutls_cipher_priority(session, params->cipher->id) < 0) return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); if (_gnutls_mac_priority(session, params->mac->id) < 0) return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); if (_gnutls_compression_is_ok(comp_algo) != 0) return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM); if (!_gnutls_version_has_explicit_iv(ver) && _gnutls_cipher_type(params->cipher) == CIPHER_BLOCK) { IV_size = _gnutls_cipher_get_iv_size(params->cipher); } else { IV_size = _gnutls_cipher_get_implicit_iv_size(params->cipher); } key_size = _gnutls_cipher_get_key_size(params->cipher); hash_size = _gnutls_mac_get_key_size(params->mac); params->etm = session->security_parameters.etm; ret = _gnutls_set_keys (session, params, hash_size, IV_size, key_size); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_init_record_state(params, ver, 1, ¶ms->read); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_init_record_state(params, ver, 0, ¶ms->write); if (ret < 0) return gnutls_assert_val(ret); params->record_sw_size = 0; _gnutls_record_log("REC[%p]: Epoch #%u ready\n", session, params->epoch); params->initialized = 1; return 0; }