Committer: Tim Just <tim.just@xxxxxxxxxxxxxx> Date: Fri Mar 05 17:28:18 2010 +0100 Revision: 3624 Revision-id: tim.just@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Branch nick: tiny Log: Refined I2 packet handling. Anyway the packet handling is still chaotic and need to be improved. Modified: M hipd/esp_prot_hipd_msg.c M hipd/esp_prot_hipd_msg.h M hipd/init.c M hipd/input.c M hipd/input.h M hipd/modularization.c M hipd/output.c M hipd/output.h M lib/core/state.h === modified file 'hipd/esp_prot_hipd_msg.c' --- hipd/esp_prot_hipd_msg.c 2010-03-05 09:51:49 +0000 +++ hipd/esp_prot_hipd_msg.c 2010-03-05 16:28:18 +0000 @@ -540,7 +540,7 @@ * @param ctx packet context for the received R1 message * @return always 0 */ -int esp_prot_r1_handle_transforms(hip_ha_t *entry, struct hip_context *ctx) +int esp_prot_r1_handle_transforms(struct hip_packet_context *packet_ctx) { struct hip_param *param = NULL; struct esp_prot_preferred_tfms *prot_transforms = NULL; @@ -551,35 +551,35 @@ if (hip_use_userspace_ipsec) { HIP_DEBUG("userspace IPsec hint: ESP extension might be in use\n"); - param = hip_get_param(ctx->input, HIP_PARAM_ESP_PROT_TRANSFORMS); + param = hip_get_param(packet_ctx->input_msg, HIP_PARAM_ESP_PROT_TRANSFORMS); // check if the transform parameter was sent if (param) { HIP_DEBUG("received preferred transforms from peer\n"); // store that we received the param for further processing - ctx->esp_prot_param = 1; + packet_ctx->hadb_entry->esp_prot_param = 1; prot_transforms = (struct esp_prot_preferred_tfms *) param; // select transform and store it for this connection - entry->esp_prot_transform = esp_prot_select_transform(prot_transforms->num_transforms, + packet_ctx->hadb_entry->esp_prot_transform = esp_prot_select_transform(prot_transforms->num_transforms, prot_transforms->transforms); } else { HIP_DEBUG("R1 does not contain preferred ESP protection " \ "transforms, locally setting UNUSED\n"); // store that we didn't received the param - ctx->esp_prot_param = 0; + packet_ctx->hadb_entry->esp_prot_param = 0; // if the other end-host does not want to use the extension, we don't either - entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; + packet_ctx->hadb_entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; } } else { HIP_DEBUG("no userspace IPsec hint for ESP extension, locally setting UNUSED\n"); // make sure we don't add the anchor now and don't add any transform or anchor - entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; + packet_ctx->hadb_entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; } return err; @@ -593,8 +593,7 @@ * @param ctx packet context for the I2 message * @return 0 on success, -1 in case of an error */ -int esp_prot_i2_add_anchor(hip_common_t *i2, hip_ha_t *entry, - const struct hip_context *ctx) +int esp_prot_i2_add_anchor(struct hip_packet_context *ctx) { unsigned char *anchor = NULL; int hash_length = 0; @@ -604,54 +603,55 @@ /* only add, if extension in use and we agreed on a transform * * @note the transform was selected in handle R1 */ - if (entry->esp_prot_transform > ESP_PROT_TFM_UNUSED) { + if (ctx->hadb_entry->esp_prot_transform > ESP_PROT_TFM_UNUSED) { // check for sufficient elements - if (anchor_db_get_num_anchors(entry->esp_prot_transform) >= esp_prot_num_parallel_hchains) { - hash_length = anchor_db_get_anchor_length(entry->esp_prot_transform); + if (anchor_db_get_num_anchors(ctx->hadb_entry->esp_prot_transform) >= + esp_prot_num_parallel_hchains) { + hash_length = anchor_db_get_anchor_length(ctx->hadb_entry->esp_prot_transform); HIP_DEBUG("hash_length: %i\n", hash_length); - hash_item_length = anchor_db_get_hash_item_length(entry->esp_prot_transform); + hash_item_length = anchor_db_get_hash_item_length(ctx->hadb_entry->esp_prot_transform); for (i = 0; i < esp_prot_num_parallel_hchains; i++) { // add all anchors now - HIP_IFEL(!(anchor = anchor_db_get_anchor(entry->esp_prot_transform)), -1, + HIP_IFEL(!(anchor = anchor_db_get_anchor(ctx->hadb_entry->esp_prot_transform)), -1, "no anchor elements available, threading?\n"); - HIP_IFEL(hip_build_param_esp_prot_anchor(i2, entry->esp_prot_transform, + HIP_IFEL(hip_build_param_esp_prot_anchor(ctx->output_msg, ctx->hadb_entry->esp_prot_transform, anchor, NULL, hash_length, hash_item_length), -1, "Building of ESP protection anchor failed\n"); // store local_anchor - memcpy(&entry->esp_local_anchors[i][0], anchor, hash_length); - HIP_HEXDUMP("stored local anchor: ", &entry->esp_local_anchors[i][0], hash_length); + memcpy(&ctx->hadb_entry->esp_local_anchors[i][0], anchor, hash_length); + HIP_HEXDUMP("stored local anchor: ", &ctx->hadb_entry->esp_local_anchors[i][0], hash_length); - entry->esp_local_active_length = hash_item_length; - HIP_DEBUG("entry->esp_local_active_length: %u\n", - entry->esp_local_active_length); + ctx->hadb_entry->esp_local_active_length = hash_item_length; + HIP_DEBUG("ctx->hadb_entry->esp_local_active_length: %u\n", + ctx->hadb_entry->esp_local_active_length); } } else { // fall back HIP_ERROR("agreed on using esp hchain protection, but not sufficient elements"); - entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; + ctx->hadb_entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; // inform our peer - HIP_IFEL(hip_build_param_esp_prot_anchor(i2, entry->esp_prot_transform, + HIP_IFEL(hip_build_param_esp_prot_anchor(ctx->output_msg, ctx->hadb_entry->esp_prot_transform, NULL, NULL, 0, 0), -1, "Building of ESP protection anchor failed\n"); } } else { // only reply, if transforms param in R1; send UNUSED param - if (ctx->esp_prot_param) { + if (ctx->hadb_entry->esp_prot_param) { HIP_DEBUG("R1 contained transforms, but agreed not to use the extension\n"); - entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; + ctx->hadb_entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; - HIP_IFEL(hip_build_param_esp_prot_anchor(i2, entry->esp_prot_transform, + HIP_IFEL(hip_build_param_esp_prot_anchor(ctx->output_msg, ctx->hadb_entry->esp_prot_transform, NULL, NULL, 0, 0), -1, "Building of ESP protection anchor failed\n"); } else { HIP_DEBUG("peer didn't send transforms in R1, locally setting UNUSED\n"); - entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; + ctx->hadb_entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; } } @@ -670,7 +670,7 @@ * @param ctx packet context for the I2 message * @return 0 on success, -1 in case of an error */ -int esp_prot_i2_handle_anchor(hip_ha_t *entry, const struct hip_context *ctx) +int esp_prot_i2_handle_anchor(struct hip_packet_context *ctx) { struct hip_tlv_common *param = NULL; struct esp_prot_anchor *prot_anchor = NULL; @@ -681,17 +681,17 @@ if (hip_use_userspace_ipsec && esp_prot_num_transforms > 1) { HIP_DEBUG("userspace IPsec hint: esp protection extension might be in use\n"); - if ((param = hip_get_param(ctx->input, HIP_PARAM_ESP_PROT_ANCHOR))) { + if ((param = hip_get_param(ctx->input_msg, HIP_PARAM_ESP_PROT_ANCHOR))) { prot_anchor = (struct esp_prot_anchor *) param; // check if the anchor has a supported transform if (esp_prot_check_transform(esp_prot_num_transforms, esp_prot_transforms, prot_anchor->transform) >= 0) { // we know this transform - entry->esp_prot_transform = prot_anchor->transform; - hash_length = anchor_db_get_anchor_length(entry->esp_prot_transform); + ctx->hadb_entry->esp_prot_transform = prot_anchor->transform; + hash_length = anchor_db_get_anchor_length(ctx->hadb_entry->esp_prot_transform); - if (entry->esp_prot_transform == ESP_PROT_TFM_UNUSED) { + if (ctx->hadb_entry->esp_prot_transform == ESP_PROT_TFM_UNUSED) { HIP_DEBUG("agreed NOT to use esp protection extension\n"); // there should be no other anchors in this case @@ -699,42 +699,42 @@ } // store number of elements per hash structure - entry->esp_peer_active_length = ntohl(prot_anchor->hash_item_length); - HIP_DEBUG("entry->esp_peer_active_length: %u\n", - entry->esp_peer_active_length); + ctx->hadb_entry->esp_peer_active_length = ntohl(prot_anchor->hash_item_length); + HIP_DEBUG("ctx->hadb_entry->esp_peer_active_length: %u\n", + ctx->hadb_entry->esp_peer_active_length); // store all contained anchors for (i = 0; i < esp_prot_num_parallel_hchains; i++) { - if (!prot_anchor || prot_anchor->transform != entry->esp_prot_transform) { + if (!prot_anchor || prot_anchor->transform != ctx->hadb_entry->esp_prot_transform) { // we expect an anchor and all anchors should have the same transform err = -1; goto out_err; } else { // store peer_anchor - memcpy(&entry->esp_peer_anchors[i][0], &prot_anchor->anchors[0], + memcpy(&ctx->hadb_entry->esp_peer_anchors[i][0], &prot_anchor->anchors[0], hash_length); - HIP_HEXDUMP("received anchor: ", &entry->esp_peer_anchors[i][0], + HIP_HEXDUMP("received anchor: ", &ctx->hadb_entry->esp_peer_anchors[i][0], hash_length); } // get next anchor - param = hip_get_next_param(ctx->input, param); + param = hip_get_next_param(ctx->input_msg, param); prot_anchor = (struct esp_prot_anchor *) param; } } else { HIP_ERROR("received anchor with unknown transform, falling back\n"); - entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; + ctx->hadb_entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; } } else { HIP_DEBUG("NO esp anchor sent, locally setting UNUSED\n"); - entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; + ctx->hadb_entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; } } else { HIP_DEBUG("userspace IPsec hint: esp protection extension NOT in use\n"); - entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; + ctx->hadb_entry->esp_prot_transform = ESP_PROT_TFM_UNUSED; } out_err: === modified file 'hipd/esp_prot_hipd_msg.h' --- hipd/esp_prot_hipd_msg.h 2010-03-05 09:51:49 +0000 +++ hipd/esp_prot_hipd_msg.h 2010-03-05 16:28:18 +0000 @@ -24,11 +24,9 @@ int esp_prot_sa_add(hip_ha_t *entry, struct hip_common *msg, const int direction, const int update); int esp_prot_r1_add_transforms(hip_common_t *msg); -int esp_prot_r1_handle_transforms(hip_ha_t *entry, struct hip_context *ctx); -int esp_prot_i2_add_anchor(hip_common_t *i2, - hip_ha_t *entry, - const struct hip_context *ctx); -int esp_prot_i2_handle_anchor(hip_ha_t *entry, const struct hip_context *ctx); +int esp_prot_r1_handle_transforms(struct hip_packet_context *packet_ctx); +int esp_prot_i2_add_anchor(struct hip_packet_context *ctx); +int esp_prot_i2_handle_anchor(struct hip_packet_context *ctx); int esp_prot_r2_add_anchor(hip_common_t *r2, hip_ha_t *entry); int esp_prot_r2_handle_anchor(hip_ha_t *entry, const struct hip_common *input_msg); === modified file 'hipd/init.c' --- hipd/init.c 2010-03-05 10:13:14 +0000 +++ hipd/init.c 2010-03-05 16:28:18 +0000 @@ -461,12 +461,16 @@ hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_handle_i2, 1000); hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_send_r2, 1100); - hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_handle_r1, 1000); - hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_handle_r1, 1000); - hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_handle_r1, 1000); - hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_handle_r1, 1000); + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_handle_r1, 1000); + hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_send_i2, 1100); + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_handle_r1, 1000); + hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_send_i2, 1100); + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_handle_r1, 1000); + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_send_i2, 1100); + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_handle_r1, 1000); + hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_send_i2, 1100); - hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_handle_r2, 1000); + hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_handle_r2, 1000); hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I1_SENT, &hip_handle_notify, 1000); hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I2_SENT, &hip_handle_notify, 1000); === modified file 'hipd/input.c' --- hipd/input.c 2010-03-05 10:30:23 +0000 +++ hipd/input.c 2010-03-05 16:28:18 +0000 @@ -216,8 +216,9 @@ * @param dhpv pointer to the DH public value choosen * @return zero on success, or negative on error. */ -int hip_produce_keying_material(struct hip_common *msg, struct hip_context *ctx, - uint64_t I, uint64_t J, +int hip_produce_keying_material(struct hip_packet_context *packet_ctx, + uint64_t I, + uint64_t J, struct hip_dh_public_value **dhpv) { char *dh_shared_key = NULL; @@ -237,12 +238,12 @@ _HIP_DEBUG("hip_produce_keying_material() invoked.\n"); /* Perform light operations first before allocating memory or * using lots of CPU time */ - HIP_IFEL(!(param = hip_get_param(msg, HIP_PARAM_HIP_TRANSFORM)), + HIP_IFEL(!(param = hip_get_param(packet_ctx->input_msg, HIP_PARAM_HIP_TRANSFORM)), -EINVAL, "Could not find HIP transform\n"); HIP_IFEL((hip_tfm = hip_select_hip_transform((struct hip_hip_transform *) param)) == 0, -EINVAL, "Could not select HIP transform\n"); - HIP_IFEL(!(param = hip_get_param(msg, HIP_PARAM_ESP_TRANSFORM)), + HIP_IFEL(!(param = hip_get_param(packet_ctx->input_msg, HIP_PARAM_ESP_TRANSFORM)), -EINVAL, "Could not find ESP transform\n"); HIP_IFEL((esp_tfm = hip_select_esp_transform((struct hip_esp_transform *) param)) == 0, @@ -273,9 +274,9 @@ hip_transf_length + hmac_transf_length; /* R1 contains no ESP_INFO */ - esp_info = hip_get_param(msg, HIP_PARAM_ESP_INFO); + esp_info = hip_get_param(packet_ctx->input_msg, HIP_PARAM_ESP_INFO); - if (esp_info != NULL) { + if (esp_info) { esp_keymat_index = ntohs(esp_info->keymat_index); } else { esp_keymat_index = esp_default_keymat_index; @@ -310,7 +311,7 @@ memset(dh_shared_key, 0, dh_shared_len); HIP_IFEL(!(dhf = (struct hip_diffie_hellman *) hip_get_param( - msg, HIP_PARAM_DIFFIE_HELLMAN)), + packet_ctx->input_msg, HIP_PARAM_DIFFIE_HELLMAN)), -ENOENT, "No Diffie-Hellman parameter found.\n"); /* If the message has two DH keys, select (the stronger, usually) one. */ @@ -335,91 +336,99 @@ _HIP_HEXDUMP("Diffie-Hellman shared key:\n", dh_shared_key, dh_shared_len); - - hip_make_keymat(dh_shared_key, dh_shared_len, - &km, keymat, keymat_len, - &msg->hits, &msg->hitr, &ctx->keymat_calc_index, I, J); + hip_make_keymat(dh_shared_key, + dh_shared_len, + &km, + keymat, + keymat_len, + &packet_ctx->input_msg->hits, + &packet_ctx->input_msg->hitr, + &packet_ctx->hadb_entry->keymat_calc_index, + I, + J); /* draw from km to keymat, copy keymat to dst, length of * keymat is len */ - we_are_HITg = hip_hit_is_bigger(&msg->hitr, &msg->hits); + we_are_HITg = hip_hit_is_bigger(&packet_ctx->input_msg->hitr, + &packet_ctx->input_msg->hits); + HIP_DEBUG("We are %s HIT.\n", we_are_HITg ? "greater" : "lesser"); if (we_are_HITg) { - hip_keymat_draw_and_copy(ctx->hip_enc_out.key, &km, - hip_transf_length); - hip_keymat_draw_and_copy(ctx->hip_hmac_out.key, &km, - hmac_transf_length); - hip_keymat_draw_and_copy(ctx->hip_enc_in.key, &km, - hip_transf_length); - hip_keymat_draw_and_copy(ctx->hip_hmac_in.key, &km, - hmac_transf_length); - hip_keymat_draw_and_copy(ctx->esp_out.key, &km, + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->hip_enc_out.key, &km, + hip_transf_length); + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->hip_hmac_out.key, &km, + hmac_transf_length); + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->hip_enc_in.key, &km, + hip_transf_length); + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->hip_hmac_in.key, &km, + hmac_transf_length); + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->esp_out.key, &km, esp_transf_length); - hip_keymat_draw_and_copy(ctx->auth_out.key, &km, + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->auth_out.key, &km, auth_transf_length); - hip_keymat_draw_and_copy(ctx->esp_in.key, &km, + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->esp_in.key, &km, esp_transf_length); - hip_keymat_draw_and_copy(ctx->auth_in.key, &km, + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->auth_in.key, &km, auth_transf_length); } else { - hip_keymat_draw_and_copy(ctx->hip_enc_in.key, &km, - hip_transf_length); - hip_keymat_draw_and_copy(ctx->hip_hmac_in.key, &km, - hmac_transf_length); - hip_keymat_draw_and_copy(ctx->hip_enc_out.key, &km, - hip_transf_length); - hip_keymat_draw_and_copy(ctx->hip_hmac_out.key, &km, - hmac_transf_length); - hip_keymat_draw_and_copy(ctx->esp_in.key, &km, + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->hip_enc_in.key, &km, + hip_transf_length); + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->hip_hmac_in.key, &km, + hmac_transf_length); + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->hip_enc_out.key, &km, + hip_transf_length); + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->hip_hmac_out.key, &km, + hmac_transf_length); + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->esp_in.key, &km, esp_transf_length); - hip_keymat_draw_and_copy(ctx->auth_in.key, &km, + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->auth_in.key, &km, auth_transf_length); - hip_keymat_draw_and_copy(ctx->esp_out.key, &km, + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->esp_out.key, &km, esp_transf_length); - hip_keymat_draw_and_copy(ctx->auth_out.key, &km, + hip_keymat_draw_and_copy(packet_ctx->hadb_entry->auth_out.key, &km, auth_transf_length); } #ifdef CONFIG_HIP_PERFORMANCE HIP_DEBUG("Stop PERF_DH_CREATE\n"); hip_perf_stop_benchmark(perf_set, PERF_DH_CREATE); #endif - HIP_HEXDUMP("HIP-gl encryption:", &ctx->hip_enc_out.key, + HIP_HEXDUMP("HIP-gl encryption:", &packet_ctx->hadb_entry->hip_enc_out.key, hip_transf_length); - HIP_HEXDUMP("HIP-gl integrity (HMAC) key:", &ctx->hip_hmac_out.key, + HIP_HEXDUMP("HIP-gl integrity (HMAC) key:", &packet_ctx->hadb_entry->hip_hmac_out.key, hmac_transf_length); _HIP_DEBUG("skipping HIP-lg encryption key, %u bytes\n", hip_transf_length); - HIP_HEXDUMP("HIP-lg encryption:", &ctx->hip_enc_in.key, + HIP_HEXDUMP("HIP-lg encryption:", &packet_ctx->hadb_entry->hip_enc_in.key, hip_transf_length); - HIP_HEXDUMP("HIP-lg integrity (HMAC) key:", &ctx->hip_hmac_in.key, + HIP_HEXDUMP("HIP-lg integrity (HMAC) key:", &packet_ctx->hadb_entry->hip_hmac_in.key, hmac_transf_length); - HIP_HEXDUMP("SA-gl ESP encryption key:", &ctx->esp_out.key, + HIP_HEXDUMP("SA-gl ESP encryption key:", &packet_ctx->hadb_entry->esp_out.key, esp_transf_length); - HIP_HEXDUMP("SA-gl ESP authentication key:", &ctx->auth_out.key, + HIP_HEXDUMP("SA-gl ESP authentication key:", &packet_ctx->hadb_entry->auth_out.key, auth_transf_length); - HIP_HEXDUMP("SA-lg ESP encryption key:", &ctx->esp_in.key, + HIP_HEXDUMP("SA-lg ESP encryption key:", &packet_ctx->hadb_entry->esp_in.key, esp_transf_length); - HIP_HEXDUMP("SA-lg ESP authentication key:", &ctx->auth_in.key, + HIP_HEXDUMP("SA-lg ESP authentication key:", &packet_ctx->hadb_entry->auth_in.key, auth_transf_length); /* the next byte when creating new keymat */ - ctx->current_keymat_index = keymat_len_min; /* offset value, so no +1 ? */ - ctx->keymat_calc_index = (ctx->current_keymat_index / HIP_AH_SHA_LEN) + 1; - ctx->esp_keymat_index = esp_keymat_index; - - memcpy(ctx->current_keymat_K, - keymat + (ctx->keymat_calc_index - 1) * HIP_AH_SHA_LEN, HIP_AH_SHA_LEN); - - _HIP_DEBUG("ctx: keymat_calc_index=%u current_keymat_index=%u\n", - ctx->keymat_calc_index, ctx->current_keymat_index); - _HIP_HEXDUMP("CTX CURRENT KEYMAT", ctx->current_keymat_K, + packet_ctx->hadb_entry->current_keymat_index = keymat_len_min; /* offset value, so no +1 ? */ + packet_ctx->hadb_entry->keymat_calc_index = (packet_ctx->hadb_entry->current_keymat_index / HIP_AH_SHA_LEN) + 1; + packet_ctx->hadb_entry->esp_keymat_index = esp_keymat_index; + + memcpy(packet_ctx->hadb_entry->current_keymat_K, + keymat + (packet_ctx->hadb_entry->keymat_calc_index - 1) * HIP_AH_SHA_LEN, HIP_AH_SHA_LEN); + + _HIP_DEBUG("packet_ctx->hadb_entry: keymat_calc_index=%u current_keymat_index=%u\n", + packet_ctx->hadb_entry->keymat_calc_index, packet_ctx->hadb_entry->current_keymat_index); + _HIP_HEXDUMP("CTX CURRENT KEYMAT", packet_ctx->hadb_entry->current_keymat_K, HIP_AH_SHA_LEN); /* store DH shared key */ - ctx->dh_shared_key = dh_shared_key; - ctx->dh_shared_key_len = dh_shared_len; + packet_ctx->hadb_entry->dh_shared_key = dh_shared_key; + packet_ctx->hadb_entry->dh_shared_key_len = dh_shared_len; /* on success HIP_FREE for dh_shared_key is called by caller */ out_err: @@ -744,15 +753,17 @@ const uint32_t ha_state, struct hip_packet_context *packet_ctx) { - int mask = HIP_PACKET_CTRL_ANON, err = 0, retransmission = 0, len; + int mask = HIP_PACKET_CTRL_ANON, err = 0, retransmission = 0, written = 0, len; uint64_t solved_puzzle = 0, I = 0; - struct hip_context *ctx = NULL; + struct hip_puzzle *pz = NULL; + struct hip_diffie_hellman *dh_req = NULL; struct hip_host_id *peer_host_id = NULL; struct hip_r1_counter *r1cntr = NULL; struct hip_dh_public_value *dhpv = NULL; struct hip_locator *locator = NULL; char *str = NULL; struct in6_addr daddr; + uint16_t i2_mask = 0; #ifdef CONFIG_HIP_PERFORMANCE HIP_DEBUG("Start PERF_R1\n"); hip_perf_start_benchmark(perf_set, PERF_R1); @@ -774,8 +785,6 @@ HIP_IFEL(!hip_controls_sane(ntohs(packet_ctx->input_msg->control), mask), 0, "Received illegal controls in R1: 0x%x Dropping\n", ntohs(packet_ctx->input_msg->control)); - HIP_IFEL(!packet_ctx->hadb_entry, -EFAULT, - "Received R1 with no local state. Dropping\n"); /* An implicit and insecure REA. If sender's address is different than * the one that was mapped, then we will overwrite the mapping with the @@ -805,11 +814,6 @@ HIP_DEBUG("Not a retransmission\n"); } - HIP_IFEL(!(ctx = HIP_MALLOC(sizeof(struct hip_context), GFP_KERNEL)), - -ENOMEM, "Could not allocate memory for context\n"); - memset(ctx, 0, sizeof(struct hip_context)); - ctx->input = packet_ctx->input_msg; - hip_relay_add_rvs_to_ha(packet_ctx->input_msg, packet_ctx->hadb_entry); /* According to the section 8.6 of the base draft, we must first check @@ -891,9 +895,11 @@ HIP_IFEL(!(pz = hip_get_param(packet_ctx->input_msg, HIP_PARAM_PUZZLE)), -EINVAL, "Malformed R1 packet. PUZZLE parameter missing\n"); - HIP_IFEL((solved_puzzle = hip_solve_puzzle(pz, packet_ctx->input_msg, HIP_SOLVE_PUZZLE)) == 0, - -EINVAL, "Solving of puzzle failed\n"); - I = pz->I; + HIP_IFEL((solved_puzzle = hip_solve_puzzle(pz, + packet_ctx->input_msg, + HIP_SOLVE_PUZZLE)) == 0, + -EINVAL, "Solving of puzzle failed\n"); + I = pz->I; packet_ctx->hadb_entry->puzzle_solution = solved_puzzle; packet_ctx->hadb_entry->puzzle_i = pz->I; } else { @@ -901,16 +907,67 @@ solved_puzzle = packet_ctx->hadb_entry->puzzle_solution; } - /* calculate shared secret and create keying material */ - ctx->dh_shared_key = NULL; + /* Allocate space for a new I2 message. */ + HIP_IFEL(!(packet_ctx->output_msg = hip_msg_alloc()), + -ENOMEM, + "Allocation of I2 failed\n"); + + HIP_DEBUG("Build normal I2.\n"); + /* create I2 */ + hip_build_network_hdr(packet_ctx->output_msg, + HIP_I2, + i2_mask, + &packet_ctx->input_msg->hitr, + &packet_ctx->input_msg->hits); + /* note: we could skip keying material generation in the case * of a retransmission but then we'd had to fill ctx->hmac etc */ - HIP_IFEL(hip_produce_keying_material(packet_ctx->input_msg, - ctx, + HIP_IFEL(hip_produce_keying_material(packet_ctx, I, solved_puzzle, &dhpv), - -EINVAL, "Could not produce keying material\n"); + -EINVAL, + "Could not produce keying material\n"); + + /********** ESP_INFO **********/ + /* SPI is set below */ + HIP_IFEL(hip_build_param_esp_info(packet_ctx->output_msg, + packet_ctx->hadb_entry->esp_keymat_index, + 0, + 0), + -1, + "building of ESP_INFO failed.\n"); + + /********** SOLUTION **********/ + HIP_IFEL(!(pz = hip_get_param(packet_ctx->input_msg, HIP_PARAM_PUZZLE)), + -ENOENT, + "Internal error: PUZZLE parameter mysteriously gone\n"); + HIP_IFEL(hip_build_param_solution(packet_ctx->output_msg, pz, ntoh64(solved_puzzle)), + -1, + "Building of solution failed\n"); + + /********** Diffie-Hellman *********/ + /* calculate shared secret and create keying material */ + packet_ctx->hadb_entry->dh_shared_key = NULL; + + HIP_IFEL(!(dh_req = hip_get_param(packet_ctx->input_msg, HIP_PARAM_DIFFIE_HELLMAN)), + -ENOENT, + "Internal error\n"); + HIP_IFEL((written = hip_insert_dh(dhpv->public_value, + ntohs(dhpv->pub_len), + dhpv->group_id)) < 0, + -1, + "Could not extract the DH public key\n"); + + HIP_IFEL(hip_build_param_diffie_hellman_contents(packet_ctx->output_msg, + dhpv->group_id, + dhpv->public_value, + written, + HIP_MAX_DH_GROUP_ID, + NULL, + 0), + -1, + "Building of DH failed.\n"); /* Everything ok, save host id to HA */ HIP_IFE(hip_get_param_host_id_di_type_len(peer_host_id, &str, &len) < 0, -1); @@ -920,36 +977,15 @@ hip_get_param_host_id_hostname(peer_host_id)); /********* ESP protection preferred transforms [OPTIONAL] *********/ - - HIP_IFEL(esp_prot_r1_handle_transforms(packet_ctx->hadb_entry, ctx), -1, + HIP_IFEL(esp_prot_r1_handle_transforms(packet_ctx), + -1, "failed to handle preferred esp protection transforms\n"); /******************************************************************/ - /* We haven't handled REG_INFO parameter. We do that in hip_send_i2() - * because we must create an REG_REQUEST parameter based on the data - * of the REG_INFO parameter. */ - - err = hip_send_i2(ctx, - solved_puzzle, - packet_ctx->src_addr, - packet_ctx->dst_addr, - packet_ctx->hadb_entry, - packet_ctx->msg_ports, - dhpv); - - HIP_IFEL(err < 0, -1, "Creation of I2 failed\n"); - - if (packet_ctx->hadb_entry->state == HIP_STATE_I1_SENT) { - packet_ctx->hadb_entry->state = HIP_STATE_I2_SENT; - } - -out_err: - if (ctx->dh_shared_key) { - HIP_FREE(ctx->dh_shared_key); - } - if (ctx) { - HIP_FREE(ctx); + out_err: + if (packet_ctx->hadb_entry->dh_shared_key) { + HIP_FREE(packet_ctx->hadb_entry->dh_shared_key); } #ifdef CONFIG_HIP_PERFORMANCE HIP_DEBUG("Stop and write PERF_R1\n"); @@ -1039,7 +1075,6 @@ in6_addr_t dest; // dest for the IP address in RELAY_FROM hip_transform_suite_t esp_tfm, hip_tfm; struct hip_spi_in_item spi_in_data; - struct hip_context i2_context; struct hip_locator *locator = NULL; int do_transform = 0; int if_index = 0; @@ -1047,8 +1082,8 @@ struct sockaddr *addr = NULL; HIP_IFEL(ctx->drop_packet, - -1, - "Abort packet processing.\n"); + -1, + "Abort packet processing.\n"); #ifdef CONFIG_HIP_PERFORMANCE HIP_DEBUG("Start PERF_I2\n"); @@ -1069,19 +1104,6 @@ HIP_INFO_HIT("Source HIT:", &(ctx->input_msg)->hits); HIP_INFO_IN6ADDR("Source IP: ", ctx->src_addr); - /* The context structure is used to gather the context created from - * processing the I2 packet, as well as storing the original packet. - * From the context struct we can then access the I2 in hip_send_r2() - * later. */ - i2_context.input = NULL; - i2_context.output = NULL; - i2_context.dh_shared_key = NULL; - - /* Store a pointer to the incoming i2 message in the context just - * allocted. From the context struct we can then access the I2 in - * hip_send_r2() later. */ - i2_context.input = ctx->input_msg; - /* Check that the Responder's HIT is one of ours. According to RFC5201, * this MUST be done. This check was added by Lauri on 01.08.2008. * Note that this condition is not satisfied at the HIP relay server */ @@ -1101,7 +1123,7 @@ * boot counter so we do not check it. */ /* Check solution for cookie */ - solution = hip_get_param(i2_context.input, HIP_PARAM_SOLUTION); + solution = hip_get_param(ctx->input_msg, HIP_PARAM_SOLUTION); if (solution == NULL) { err = -ENODATA; HIP_ERROR("SOLUTION parameter missing from I2 packet. " \ @@ -1125,7 +1147,16 @@ } else if (ctx->hadb_entry->state == HIP_STATE_ESTABLISHED) { retransmission = 1; } - } + } else { + HIP_DEBUG("No HIP association found. Creating a new one.\n"); + + if ((ctx->hadb_entry = hip_hadb_create_state(GFP_KERNEL)) == NULL) { + err = -ENOMEM; + HIP_ERROR("Out of memory when allocating memory for a new " \ + "HIP association. Dropping the I2 packet.\n"); + goto out_err; + } + } /* Check HIP and ESP transforms, and produce keying material. */ @@ -1135,24 +1166,29 @@ * which is set from haDB. Usually you shouldn't have state here, * right? */ - HIP_IFEL(hip_produce_keying_material(i2_context.input, &i2_context, - solution->I, solution->J, &dhpv), - -EPROTO, "Unable to produce keying material. Dropping the I2" \ - " packet.\n"); - + HIP_IFEL(hip_produce_keying_material(ctx, + solution->I, + solution->J, + &dhpv), + -EPROTO, + "Unable to produce keying material. Dropping the I2 packet.\n"); /* Verify HMAC. */ if (hip_hidb_hit_is_our(&(ctx->input_msg)->hits) && - hip_hidb_hit_is_our(&(ctx->input_msg)->hitr)) - { + hip_hidb_hit_is_our(&(ctx->input_msg)->hitr)) { + is_loopback = 1; - HIP_IFEL(hip_verify_packet_hmac(ctx->input_msg, &i2_context.hip_hmac_out), - -EPROTO, "HMAC loopback validation on I2 failed. " \ - "Dropping the I2 packet.\n"); + HIP_IFEL(hip_verify_packet_hmac(ctx->input_msg, + &ctx->hadb_entry->hip_hmac_out), + -EPROTO, + "HMAC loopback validation on I2 failed. " \ + "Dropping the I2 packet.\n"); } else { - HIP_IFEL(hip_verify_packet_hmac(ctx->input_msg, &i2_context.hip_hmac_in), - -EPROTO, "HMAC validation on I2 failed. Dropping the" \ - " I2 packet.\n"); + HIP_IFEL(hip_verify_packet_hmac(ctx->input_msg, + &ctx->hadb_entry->hip_hmac_in), + -EPROTO, + "HMAC validation on I2 failed. Dropping the" \ + " I2 packet.\n"); } hip_transform = hip_get_param(ctx->input_msg, HIP_PARAM_HIP_TRANSFORM); @@ -1170,6 +1206,7 @@ do_transform = 1; } + /* Decrypt the HOST_ID and verify it against the sender HIT. */ /* @todo: the HOST_ID can be in the packet in plain text */ enc = hip_get_param(ctx->input_msg, HIP_PARAM_ENCRYPTED); @@ -1278,8 +1315,9 @@ * Note, that the original packet has the data still encrypted. */ if (!host_id_found) { HIP_IFEL(hip_crypto_encrypted(host_id_in_enc, iv, hip_tfm, crypto_len, - (is_loopback ? &i2_context.hip_enc_out.key : - &i2_context.hip_enc_in.key), + (is_loopback ? + &ctx->hadb_entry->hip_enc_out.key : + &ctx->hadb_entry->hip_enc_in.key), HIP_DIRECTION_DECRYPT), #ifdef CONFIG_HIP_OPENWRT // workaround for non-included errno-base.h in openwrt @@ -1303,23 +1341,6 @@ HIP_HEXDUMP("Initiator host id", host_id_in_enc, hip_get_param_total_len(host_id_in_enc)); - /* If there is no HIP association, we must create one now. */ - if (ctx->hadb_entry == NULL) { - HIP_DEBUG("No HIP association found. Creating a new one.\n"); - - if ((ctx->hadb_entry = hip_hadb_create_state(GFP_KERNEL)) == NULL) { - err = -ENOMEM; - HIP_ERROR("Out of memory when allocating memory for a new " \ - "HIP association. Dropping the I2 packet.\n"); - goto out_err; - } - } - - //ctx->hadb_entry->hip_nat_key = i2_context.hip_nat_key; - //HIP_DEBUG("hip nat key from context %s", i2_context.hip_nat_key); - memcpy(ctx->hadb_entry->hip_nat_key, i2_context.hip_nat_key, HIP_MAX_KEY_LEN); - //HIP_DEBUG("hip nat key in entry %s", ctx->hadb_entry->hip_nat_key); - if (spi_in == 0) { spi_in = ctx->hadb_entry->spi_inbound_current; HIP_DEBUG("inbound IPsec SA, SPI=0x%x (host)\n", spi_in); @@ -1404,7 +1425,9 @@ HIP_DEBUG("Start PERF_VERIFY(2)\n"); hip_perf_start_benchmark(perf_set, PERF_VERIFY); #endif - HIP_IFEL(ctx->hadb_entry->verify(ctx->hadb_entry->peer_pub_key, i2_context.input), -EINVAL, + HIP_IFEL(ctx->hadb_entry->verify(ctx->hadb_entry->peer_pub_key, + ctx->input_msg), + -EINVAL, "Verification of I2 signature failed\n"); #ifdef CONFIG_HIP_PERFORMANCE HIP_DEBUG("Stop PERF_VERIFY(2)\n"); @@ -1418,10 +1441,10 @@ struct hip_esp_transform *esp_tf = NULL; struct hip_spi_out_item spi_out_data; - HIP_IFEL(!(esp_tf = hip_get_param(i2_context.input, + HIP_IFEL(!(esp_tf = hip_get_param(ctx->input_msg, HIP_PARAM_ESP_TRANSFORM)), -ENOENT, "Did not find ESP transform on i2\n"); - HIP_IFEL(!(esp_info = hip_get_param(i2_context.input, + HIP_IFEL(!(esp_info = hip_get_param(ctx->input_msg, HIP_PARAM_ESP_INFO)), -ENOENT, "Did not find SPI LSI on i2\n"); @@ -1457,8 +1480,8 @@ ctx->msg_ports->dst_port); /********** ESP-PROT anchor [OPTIONAL] **********/ - - HIP_IFEL(esp_prot_i2_handle_anchor(ctx->hadb_entry, &i2_context), -1, + /** @todo Modularize esp_prot_* */ + HIP_IFEL(esp_prot_i2_handle_anchor(ctx), -1, "failed to handle esp prot anchor\n"); /************************************************/ @@ -1466,12 +1489,12 @@ /* Set up IPsec associations */ err = hip_add_sa(ctx->src_addr, ctx->dst_addr, - &i2_context.input->hits, - &i2_context.input->hitr, + &ctx->input_msg->hits, + &ctx->input_msg->hitr, spi_in, esp_tfm, - &i2_context.esp_in, - &i2_context.auth_in, + &ctx->hadb_entry->esp_in, + &ctx->hadb_entry->auth_in, retransmission, HIP_SPI_DIRECTION_IN, 0, @@ -1490,8 +1513,8 @@ spi_out = ntohl(esp_info->new_spi); HIP_DEBUG("Setting up outbound IPsec SA, SPI=0x%x\n", spi_out); - HIP_IFEL(hip_setup_hit_sp_pair(&i2_context.input->hits, - &i2_context.input->hitr, + HIP_IFEL(hip_setup_hit_sp_pair(&ctx->input_msg->hits, + &ctx->input_msg->hitr, ctx->src_addr, ctx->dst_addr, IPPROTO_ESP, @@ -1520,7 +1543,7 @@ * */ ctx->hadb_entry->spi_outbound_new = spi_out; - HIP_IFE(hip_store_base_exchange_keys(ctx->hadb_entry, &i2_context, 0), -1); + //HIP_IFE(hip_store_base_exchange_keys(ctx->hadb_entry, &i2_context, 0), -1); //hip_hadb_insert_state(ctx->hadb_entry); HIP_DEBUG("\nInserted a new host association state.\n" @@ -1586,8 +1609,11 @@ if (tmp_enc != NULL) { free(tmp_enc); } - if (i2_context.dh_shared_key != NULL) { - free(i2_context.dh_shared_key); + if (ctx->hadb_entry->dh_shared_key != NULL) { + free(ctx->hadb_entry->dh_shared_key); + } + if (err) { + ctx->drop_packet = 1; } return err; } === modified file 'hipd/input.h' --- hipd/input.h 2010-03-05 10:30:23 +0000 +++ hipd/input.h 2010-03-05 16:28:18 +0000 @@ -113,7 +113,9 @@ const uint32_t ha_state, struct hip_packet_context *packet_ctx); -int hip_produce_keying_material(struct hip_common *msg, struct hip_context *ctx, - uint64_t I, uint64_t J, struct hip_dh_public_value **dhpv); +int hip_produce_keying_material(struct hip_packet_context *packet_ctx, + uint64_t I, + uint64_t J, + struct hip_dh_public_value **dhpv); #endif /* HIP_HIPD_INPUT_H */ === modified file 'hipd/modularization.c' --- hipd/modularization.c 2010-03-05 10:01:58 +0000 +++ hipd/modularization.c 2010-03-05 16:28:18 +0000 @@ -162,8 +162,9 @@ packet_type, ha_state); - while ((iter = - hip_ll_iterate(hip_handle_functions[packet_type][ha_state], iter))) { + while ((iter = hip_ll_iterate(hip_handle_functions[packet_type][ha_state], + iter)) + && !ctx->drop_packet) { ((struct handle_function *) iter->ptr)->func_ptr(packet_type, ha_state, === modified file 'hipd/output.c' --- hipd/output.c 2010-03-05 10:30:23 +0000 +++ hipd/output.c 2010-03-05 16:28:18 +0000 @@ -519,99 +519,63 @@ * * @return zero on success, non-negative on error. */ -int hip_send_i2(struct hip_context *ctx, uint64_t solved_puzzle, - in6_addr_t *r1_saddr, in6_addr_t *r1_daddr, hip_ha_t *entry, - hip_portpair_t *r1_info, struct hip_dh_public_value *dhpv) +int hip_send_i2(const uint32_t packet_type, + const uint32_t ha_state, + struct hip_packet_context *packet_ctx) { hip_transform_suite_t transform_hip_suite, transform_esp_suite; struct hip_spi_in_item spi_in_data; in6_addr_t daddr; struct hip_param *param = NULL; - struct hip_diffie_hellman *dh_req = NULL; struct hip_esp_info *esp_info = NULL; struct hip_host_id_entry *host_id_entry = NULL; - hip_common_t *i2 = NULL; char *enc_in_msg = NULL, *host_id_in_enc = NULL; unsigned char *iv = NULL; - int err = 0, host_id_in_enc_len = 0, written = 0; - uint16_t mask = 0; + int err = 0, host_id_in_enc_len = 0; uint32_t spi_in = 0; - _HIP_DEBUG("hip_create_i2() invoked.\n"); + HIP_IFEL(packet_ctx->drop_packet, + -1, + "Abort packet processing.\n"); + + /* We haven't handled REG_INFO parameter. We do that in hip_send_i2() + * because we must create an REG_REQUEST parameter based on the data + * of the REG_INFO parameter. */ HIP_DEBUG("R1 source port %u, destination port %d\n", - r1_info->src_port, r1_info->dst_port); - - HIP_ASSERT(entry); - - spi_in = entry->spi_inbound_current; - - /* Allocate space for a new I2 message. */ - HIP_IFEL(!(i2 = hip_msg_alloc()), -ENOMEM, "Allocation of I2 failed\n"); + packet_ctx->msg_ports->src_port, packet_ctx->msg_ports->dst_port); + + HIP_ASSERT(packet_ctx->hadb_entry); + + spi_in = packet_ctx->hadb_entry->spi_inbound_current; /* TLV sanity checks are are already done by the caller of this * function. Now, begin to build I2 piece by piece. */ /* Delete old SPDs and SAs, if present */ - hip_delete_security_associations_and_sp(entry); - - HIP_DEBUG("Build normal I2.\n"); - /* create I2 */ - hip_build_network_hdr(i2, HIP_I2, mask, &(ctx->input->hitr), &(ctx->input->hits)); - - /********** ESP_INFO **********/ - /* SPI is set below */ - HIP_IFEL(hip_build_param_esp_info(i2, ctx->esp_keymat_index, 0, 0), - -1, "building of ESP_INFO failed.\n"); + hip_delete_security_associations_and_sp(packet_ctx->hadb_entry); /********** R1 COUNTER (OPTIONAL) ********/ /* we build this, if we have recorded some value (from previous R1s) */ { uint64_t rtmp; - HIP_LOCK_HA(entry); - rtmp = entry->birthday; - HIP_UNLOCK_HA(entry); + HIP_LOCK_HA(packet_ctx->hadb_entry); + rtmp = packet_ctx->hadb_entry->birthday; + HIP_UNLOCK_HA(packet_ctx->hadb_entry); - HIP_IFEL(rtmp && hip_build_param_r1_counter(i2, rtmp), -1, + HIP_IFEL(rtmp && hip_build_param_r1_counter(packet_ctx->output_msg, rtmp), -1, "Could not build R1 GENERATION parameter\n"); } - /********** SOLUTION **********/ - { - struct hip_puzzle *pz; - - HIP_IFEL(!(pz = hip_get_param(ctx->input, HIP_PARAM_PUZZLE)), -ENOENT, - "Internal error: PUZZLE parameter mysteriously gone\n"); - HIP_IFEL(hip_build_param_solution(i2, pz, ntoh64(solved_puzzle)), -1, - "Building of solution failed\n"); - } - - /********** Diffie-Hellman *********/ - HIP_IFEL(!(dh_req = hip_get_param(ctx->input, HIP_PARAM_DIFFIE_HELLMAN)), - -ENOENT, "Internal error\n"); - HIP_IFEL((written = hip_insert_dh(dhpv->public_value, - ntohs(dhpv->pub_len), dhpv->group_id)) < 0, - -1, "Could not extract the DH public key\n"); - - HIP_IFEL(hip_build_param_diffie_hellman_contents(i2, - dhpv->group_id, - dhpv->public_value, - written, - HIP_MAX_DH_GROUP_ID, - NULL, - 0), - -1, - "Building of DH failed.\n"); - /********** HIP transform. **********/ - HIP_IFE(!(param = hip_get_param(ctx->input, HIP_PARAM_HIP_TRANSFORM)), -ENOENT); + HIP_IFE(!(param = hip_get_param(packet_ctx->input_msg, HIP_PARAM_HIP_TRANSFORM)), -ENOENT); HIP_IFEL((transform_hip_suite = hip_select_hip_transform((struct hip_hip_transform *) param)) == 0, -EINVAL, "Could not find acceptable hip transform suite\n"); /* Select only one transform */ - HIP_IFEL(hip_build_param_hip_transform(i2, + HIP_IFEL(hip_build_param_hip_transform(packet_ctx->output_msg, &transform_hip_suite, 1), -1, "Building of HIP transform failed\n"); @@ -621,11 +585,11 @@ if (hip_encrypt_i2_hi) { switch (transform_hip_suite) { case HIP_HIP_AES_SHA1: - HIP_IFEL(hip_build_param_encrypted_aes_sha1(i2, - (struct hip_tlv_common *) entry->our_pub), + HIP_IFEL(hip_build_param_encrypted_aes_sha1(packet_ctx->output_msg, + (struct hip_tlv_common *) packet_ctx->hadb_entry->our_pub), -1, "Building of param encrypted failed.\n"); - enc_in_msg = hip_get_param(i2, HIP_PARAM_ENCRYPTED); + enc_in_msg = hip_get_param(packet_ctx->output_msg, HIP_PARAM_ENCRYPTED); HIP_ASSERT(enc_in_msg); /* Builder internal error. */ iv = ((struct hip_encrypted_aes_sha1 *) enc_in_msg)->iv; get_random_bytes(iv, 16); @@ -633,9 +597,9 @@ sizeof(struct hip_encrypted_aes_sha1); break; case HIP_HIP_3DES_SHA1: - HIP_IFEL(hip_build_param_encrypted_3des_sha1(i2, (struct hip_tlv_common *) entry->our_pub), + HIP_IFEL(hip_build_param_encrypted_3des_sha1(packet_ctx->output_msg, (struct hip_tlv_common *) packet_ctx->hadb_entry->our_pub), -1, "Building of param encrypted failed.\n"); - enc_in_msg = hip_get_param(i2, HIP_PARAM_ENCRYPTED); + enc_in_msg = hip_get_param(packet_ctx->output_msg, HIP_PARAM_ENCRYPTED); HIP_ASSERT(enc_in_msg); /* Builder internal error. */ iv = ((struct hip_encrypted_3des_sha1 *) enc_in_msg)->iv; get_random_bytes(iv, 8); @@ -643,9 +607,9 @@ sizeof(struct hip_encrypted_3des_sha1); break; case HIP_HIP_NULL_SHA1: - HIP_IFEL(hip_build_param_encrypted_null_sha1(i2, (struct hip_tlv_common *) entry->our_pub), + HIP_IFEL(hip_build_param_encrypted_null_sha1(packet_ctx->output_msg, (struct hip_tlv_common *) packet_ctx->hadb_entry->our_pub), -1, "Building of param encrypted failed.\n"); - enc_in_msg = hip_get_param(i2, HIP_PARAM_ENCRYPTED); + enc_in_msg = hip_get_param(packet_ctx->output_msg, HIP_PARAM_ENCRYPTED); HIP_ASSERT(enc_in_msg); /* Builder internal error. */ iv = NULL; host_id_in_enc = enc_in_msg + @@ -660,7 +624,7 @@ * the argument pointer, so we have to allocate some extra memory */ HIP_IFEL(!(host_id_entry = hip_get_hostid_entry_by_lhi_and_algo(HIP_DB_LOCAL_HID, - &(ctx->input->hitr), + &packet_ctx->input_msg->hitr, HIP_ANY_ALGO, -1)), -1, @@ -669,29 +633,30 @@ _HIP_DEBUG("This HOST ID belongs to: %s\n", hip_get_param_host_id_hostname(host_id_entry->host_id)); - HIP_IFEL(hip_build_param(i2, host_id_entry->host_id), + HIP_IFEL(hip_build_param(packet_ctx->output_msg, host_id_entry->host_id), -1, "Building of host id failed\n"); } /* REG_INFO parameter. This builds a REG_REQUEST parameter in the I2 * packet. */ - hip_handle_param_reg_info(entry, ctx->input, i2); + hip_handle_param_reg_info(packet_ctx->hadb_entry, packet_ctx->input_msg, packet_ctx->output_msg); /********** ESP-ENC transform. **********/ - HIP_IFE(!(param = hip_get_param(ctx->input, HIP_PARAM_ESP_TRANSFORM)), -ENOENT); + HIP_IFE(!(param = hip_get_param(packet_ctx->input_msg, HIP_PARAM_ESP_TRANSFORM)), -ENOENT); /* Select only one transform */ HIP_IFEL((transform_esp_suite = hip_select_esp_transform((struct hip_esp_transform *) param)) == 0, -1, "Could not find acceptable hip transform suite\n"); - HIP_IFEL(hip_build_param_esp_transform(i2, + HIP_IFEL(hip_build_param_esp_transform(packet_ctx->output_msg, &transform_esp_suite, 1), -1, "Building of ESP transform failed\n"); /********** ESP-PROT anchor [OPTIONAL] **********/ - HIP_IFEL(esp_prot_i2_add_anchor(i2, entry, ctx), -1, + /** @todo Modularize esp_prot_* */ + HIP_IFEL(esp_prot_i2_add_anchor(packet_ctx), -1, "failed to add esp protection anchor\n"); /************************************************/ @@ -718,7 +683,7 @@ hip_get_param_total_len(host_id_in_enc)); _HIP_HEXDUMP("encinmsg", enc_in_msg, hip_get_param_total_len(enc_in_msg)); - HIP_HEXDUMP("enc key", &ctx->hip_enc_out.key, HIP_MAX_KEY_LEN); + HIP_HEXDUMP("enc key", &packet_ctx->hadb_entry->hip_enc_out.key, HIP_MAX_KEY_LEN); _HIP_HEXDUMP("IV", iv, 16); // or 8 HIP_DEBUG("host id type: %d\n", hip_get_host_id_algo((struct hip_host_id *) host_id_in_enc)); @@ -728,7 +693,7 @@ HIP_IFEL(hip_crypto_encrypted(host_id_in_enc, iv, transform_hip_suite, host_id_in_enc_len, - &ctx->hip_enc_out.key, + &packet_ctx->hadb_entry->hip_enc_out.key, HIP_DIRECTION_ENCRYPT), -1, "Building of param encrypted failed\n"); @@ -740,24 +705,24 @@ /* Now that almost everything is set up except the signature, we can * try to set up inbound IPsec SA, similarly as in hip_send_r2 */ - HIP_DEBUG("src %d, dst %d\n", r1_info->src_port, r1_info->dst_port); - - entry->local_udp_port = r1_info->src_port; - entry->peer_udp_port = r1_info->dst_port; - - entry->hip_transform = transform_hip_suite; + HIP_DEBUG("src %d, dst %d\n", packet_ctx->msg_ports->src_port, packet_ctx->msg_ports->dst_port); + + packet_ctx->hadb_entry->local_udp_port = packet_ctx->msg_ports->src_port; + packet_ctx->hadb_entry->peer_udp_port = packet_ctx->msg_ports->dst_port; + + packet_ctx->hadb_entry->hip_transform = transform_hip_suite; /* XXX: -EAGAIN */ HIP_DEBUG("set up inbound IPsec SA, SPI=0x%x (host)\n", spi_in); - HIP_IFEL(hip_setup_hit_sp_pair(&ctx->input->hits, - &ctx->input->hitr, - r1_saddr, r1_daddr, + HIP_IFEL(hip_setup_hit_sp_pair(&packet_ctx->input_msg->hits, + &packet_ctx->input_msg->hitr, + packet_ctx->src_addr, packet_ctx->dst_addr, IPPROTO_ESP, 1, 1), -1, "Setting up SP pair failed\n"); - esp_info = hip_get_param(i2, HIP_PARAM_ESP_INFO); + esp_info = hip_get_param(packet_ctx->output_msg, HIP_PARAM_ESP_INFO); HIP_ASSERT(esp_info); /* Builder internal error */ esp_info->new_spi = htonl(spi_in); /* LSI not created, as it is local, and we do not support IPv4 */ @@ -767,16 +732,16 @@ { struct hip_echo_request *ping; - ping = hip_get_param(ctx->input, HIP_PARAM_ECHO_REQUEST_SIGN); + ping = hip_get_param(packet_ctx->input_msg, HIP_PARAM_ECHO_REQUEST_SIGN); if (ping) { int ln = hip_get_param_contents_len(ping); - HIP_IFEL(hip_build_param_echo(i2, ping + 1, ln, 1, 0), -1, + HIP_IFEL(hip_build_param_echo(packet_ctx->output_msg, ping + 1, ln, 1, 0), -1, "Error while creating echo reply parameter\n"); } } /************* HMAC ************/ - HIP_IFEL(hip_build_param_hmac_contents(i2, &ctx->hip_hmac_out), + HIP_IFEL(hip_build_param_hmac_contents(packet_ctx->output_msg, &packet_ctx->hadb_entry->hip_hmac_out), -1, "Building of HMAC failed\n"); /********** Signature **********/ @@ -786,7 +751,7 @@ HIP_DEBUG("Start PERF_SIGN\n"); hip_perf_start_benchmark(perf_set, PERF_SIGN); #endif - HIP_IFEL(entry->sign(entry->our_priv_key, i2), -EINVAL, "Could not create signature\n"); + HIP_IFEL(packet_ctx->hadb_entry->sign(packet_ctx->hadb_entry->our_priv_key, packet_ctx->output_msg), -EINVAL, "Could not create signature\n"); #ifdef CONFIG_HIP_PERFORMANCE HIP_DEBUG("Stop PERF_SIGN\n"); hip_perf_stop_benchmark(perf_set, PERF_SIGN); @@ -797,10 +762,10 @@ { struct hip_echo_request *ping; - ping = hip_get_param(ctx->input, HIP_PARAM_ECHO_REQUEST); + ping = hip_get_param(packet_ctx->input_msg, HIP_PARAM_ECHO_REQUEST); if (ping) { int ln = hip_get_param_contents_len(ping); - HIP_IFEL(hip_build_param_echo(i2, (ping + 1), ln, 0, 0), -1, + HIP_IFEL(hip_build_param_echo(packet_ctx->output_msg, (ping + 1), ln, 0, 0), -1, "Error while creating echo reply parameter\n"); } } @@ -808,30 +773,41 @@ /********** I2 packet complete **********/ memset(&spi_in_data, 0, sizeof(struct hip_spi_in_item)); spi_in_data.spi = spi_in; - spi_in_data.ifindex = hip_devaddr2ifindex(r1_daddr); - HIP_LOCK_HA(entry); - - // 99999 HIP_IFEB(hip_hadb_add_spi_old(entry, HIP_SPI_DIRECTION_IN, &spi_in_data), -1, HIP_UNLOCK_HA(entry)); - - entry->esp_transform = transform_esp_suite; - HIP_DEBUG("Saving base exchange encryption data to entry \n"); - HIP_DEBUG_HIT("Our HIT: ", &entry->hit_our); - HIP_DEBUG_HIT("Peer HIT: ", &entry->hit_peer); + spi_in_data.ifindex = hip_devaddr2ifindex(packet_ctx->dst_addr); + HIP_LOCK_HA(packet_ctx->hadb_entry); + + // 99999 HIP_IFEB(hip_hadb_add_spi_old(packet_ctx->hadb_entry, HIP_SPI_DIRECTION_IN, &spi_in_data), -1, HIP_UNLOCK_HA(packet_ctx->hadb_entry)); + + packet_ctx->hadb_entry->esp_transform = transform_esp_suite; + HIP_DEBUG("Saving base exchange encryption data to packet_ctx->hadb_entry \n"); + HIP_DEBUG_HIT("Our HIT: ", &packet_ctx->hadb_entry->hit_our); + HIP_DEBUG_HIT("Peer HIT: ", &packet_ctx->hadb_entry->hit_peer); /* Store the keys until we receive R2 */ - HIP_IFEB(hip_store_base_exchange_keys(entry, ctx, 1), -1, HIP_UNLOCK_HA(entry)); + //HIP_IFEB(hip_store_base_exchange_keys(packet_ctx->hadb_entry, ctx, 1), -1, HIP_UNLOCK_HA(packet_ctx->hadb_entry)); +// hip_update_entry_keymat(packet_ctx->hadb_entry, +// packet_ctx->hadb_entry->current_keymat_index, +// packet_ctx->hadb_entry->keymat_calc_index, +// packet_ctx->hadb_entry->esp_keymat_index, +// packet_ctx->hadb_entry->current_keymat_K); /** @todo Also store the keys that will be given to ESP later */ - HIP_IFE(hip_hadb_get_peer_addr(entry, &daddr), -1); + HIP_IFE(hip_hadb_get_peer_addr(packet_ctx->hadb_entry, &daddr), -1); /* R1 packet source port becomes the I2 packet destination port. */ - err = hip_send_pkt(r1_daddr, &daddr, - (entry->nat_mode ? hip_get_local_nat_udp_port() : 0), - r1_info->src_port, i2, entry, 1); + err = hip_send_pkt(packet_ctx->dst_addr, &daddr, + (packet_ctx->hadb_entry->nat_mode ? hip_get_local_nat_udp_port() : 0), + packet_ctx->msg_ports->src_port, packet_ctx->output_msg, packet_ctx->hadb_entry, 1); HIP_IFEL(err < 0, -ECOMM, "Sending I2 packet failed.\n"); + HIP_IFEL(err < 0, -1, "Creation of I2 failed\n"); + + if (packet_ctx->hadb_entry->state == HIP_STATE_I1_SENT) { + packet_ctx->hadb_entry->state = HIP_STATE_I2_SENT; + } + out_err: - if (i2) { - HIP_FREE(i2); + if (packet_ctx->output_msg) { + HIP_FREE(packet_ctx->output_msg); } return err; @@ -1239,7 +1215,6 @@ struct hip_crypto_key hmac; int err = 0; uint16_t mask = 0; - uint32_t spi_in = 0; HIP_IFEL(packet_ctx->drop_packet, -1, @@ -1259,11 +1234,10 @@ HIP_DUMP_MSG(packet_ctx->output_msg); /* ESP_INFO */ - spi_in = packet_ctx->hadb_entry->spi_inbound_current; HIP_IFEL(hip_build_param_esp_info(packet_ctx->output_msg, packet_ctx->hadb_entry->esp_keymat_index, 0, - spi_in), + packet_ctx->hadb_entry->spi_inbound_current), -1, "building of ESP_INFO failed.\n"); === modified file 'hipd/output.h' --- hipd/output.h 2010-03-05 10:30:23 +0000 +++ hipd/output.h 2010-03-05 16:28:18 +0000 @@ -67,9 +67,9 @@ int hip_send_i1(hip_hit_t *, hip_hit_t *, hip_ha_t *); -int hip_send_i2(struct hip_context *ctx, uint64_t solved_puzzle, - in6_addr_t *r1_saddr, in6_addr_t *r1_daddr, hip_ha_t *entry, - hip_portpair_t *r1_info, struct hip_dh_public_value *dhpv); +int hip_send_i2(const uint32_t packet_type, + const uint32_t ha_state, + struct hip_packet_context *packet_ctx); int are_addresses_compatible(const struct in6_addr *src_addr, const struct in6_addr *dst_addr); === modified file 'lib/core/state.h' --- lib/core/state.h 2010-03-02 13:47:43 +0000 +++ lib/core/state.h 2010-03-05 16:28:18 +0000 @@ -319,6 +319,8 @@ int hip_transform; /** ESP extension protection transform */ uint8_t esp_prot_transform; + /** ESP extension protection parameter */ + int esp_prot_param; /** ESP extension protection local_anchor */ unsigned char esp_local_anchors[MAX_NUM_PARALLEL_HCHAINS][MAX_HASH_LENGTH]; /** another local anchor used for UPDATE messages */