Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ims_ipsec_pcscf: more algorithms, SA improvements #2731

Merged
merged 3 commits into from
May 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 19 additions & 10 deletions src/modules/ims_ipsec_pcscf/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,29 +435,29 @@ static int create_ipsec_tunnel(const struct ip_addr *remote_addr, ipsec_t* s)
return -1;
}

LM_DBG("Creating security associations: Local IP: %.*s port_pc: %d port_ps: %d; UE IP: %s; port_uc %d port_us %d; spi_pc %u, spi_ps %u, spi_uc %u, spi_us %u\n",
LM_DBG("Creating security associations: Local IP: %.*s port_pc: %d port_ps: %d; UE IP: %s; port_uc %d port_us %d; spi_pc %u, spi_ps %u, spi_uc %u, spi_us %u, alg %.*s, ealg %.*s\n",
remote_addr->af == AF_INET ? ipsec_listen_addr.len : ipsec_listen_addr6.len,
remote_addr->af == AF_INET ? ipsec_listen_addr.s : ipsec_listen_addr6.s,
s->port_pc, s->port_ps, remote_addr_str, s->port_uc, s->port_us, s->spi_pc, s->spi_ps, s->spi_uc, s->spi_us);
s->port_pc, s->port_ps, remote_addr_str, s->port_uc, s->port_us, s->spi_pc, s->spi_ps, s->spi_uc, s->spi_us, s->r_alg.len, s->r_alg.s, s->r_ealg.len, s->r_ealg.s);

// SA1 UE client to P-CSCF server
// src adrr dst addr src port dst port
add_sa (sock, remote_addr, ipsec_addr, s->port_uc, s->port_ps, s->spi_ps, s->ck, s->ik, s->r_alg);
add_sa (sock, remote_addr, ipsec_addr, s->port_uc, s->port_ps, s->spi_ps, s->ck, s->ik, s->r_alg, s->r_ealg);
add_policy(sock, remote_addr, ipsec_addr, s->port_uc, s->port_ps, s->spi_ps, IPSEC_POLICY_DIRECTION_IN);

// SA2 P-CSCF client to UE server
// src adrr dst addr src port dst port
add_sa (sock, ipsec_addr, remote_addr, s->port_pc, s->port_us, s->spi_us, s->ck, s->ik, s->r_alg);
add_sa (sock, ipsec_addr, remote_addr, s->port_pc, s->port_us, s->spi_us, s->ck, s->ik, s->r_alg, s->r_ealg);
add_policy(sock, ipsec_addr, remote_addr, s->port_pc, s->port_us, s->spi_us, IPSEC_POLICY_DIRECTION_OUT);

// SA3 P-CSCF server to UE client
// src adrr dst addr src port dst port
add_sa (sock, ipsec_addr, remote_addr, s->port_ps, s->port_uc, s->spi_uc, s->ck, s->ik, s->r_alg);
add_sa (sock, ipsec_addr, remote_addr, s->port_ps, s->port_uc, s->spi_uc, s->ck, s->ik, s->r_alg, s->r_ealg);
add_policy(sock, ipsec_addr, remote_addr, s->port_ps, s->port_uc, s->spi_uc, IPSEC_POLICY_DIRECTION_OUT);

// SA4 UE server to P-CSCF client
// src adrr dst addr src port dst port
add_sa (sock, remote_addr, ipsec_addr, s->port_us, s->port_pc, s->spi_pc, s->ck, s->ik, s->r_alg);
add_sa (sock, remote_addr, ipsec_addr, s->port_us, s->port_pc, s->spi_pc, s->ck, s->ik, s->r_alg, s->r_ealg);
add_policy(sock, remote_addr, ipsec_addr, s->port_us, s->port_pc, s->spi_pc, IPSEC_POLICY_DIRECTION_IN);

close_mnl_socket(sock);
Expand Down Expand Up @@ -846,11 +846,20 @@ int ipsec_forward(struct sip_msg* m, udomain_t* d, int _cflags)
// for Reply get the dest proto from the received request
dst_proto = req->rcv.proto;

// for Reply and TCP sends from P-CSCF server port, for Reply and UDP sends from P-CSCF client port
src_port = dst_proto == PROTO_TCP ? s->port_ps : s->port_pc;
// Check send socket
struct socket_info * client_sock = grep_sock_info(via_host.af == AF_INET ? &ipsec_listen_addr : &ipsec_listen_addr6, src_port, dst_proto);
if(client_sock) {
// for Reply and TCP sends from P-CSCF server port, for Reply and UDP sends from P-CSCF client port
src_port = dst_proto == PROTO_TCP ? s->port_ps : s->port_pc;

// for Reply and TCP sends to UE client port, for Reply and UDP sends to UE server port
dst_port = dst_proto == PROTO_TCP ? s->port_uc : s->port_us;
// for Reply and TCP sends to UE client port, for Reply and UDP sends to UE server port
dst_port = dst_proto == PROTO_TCP ? s->port_uc : s->port_us;
}
else
{
src_port = s->port_pc;
dst_port = s->port_us;
}
henningw marked this conversation as resolved.
Show resolved Hide resolved
}else{
// for Request get the dest proto from the saved contact
dst_proto = pcontact->received_proto;
Expand Down
34 changes: 32 additions & 2 deletions src/modules/ims_ipsec_pcscf/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,15 @@ static void string_to_key(char* dst, const str key_string)
}
}

static uint choose_nlmsg_seq (void)
henningw marked this conversation as resolved.
Show resolved Hide resolved
{
static double Tini=0;
struct timespec ts;
ksr_clock_gettime(&ts);
return(1000*(ts.tv_sec - Tini + (ts.tv_nsec * 1E-9))); // us
}

int add_sa(struct mnl_socket* nl_sock, const struct ip_addr *src_addr_param, const struct ip_addr *dest_addr_param, int s_port, int d_port, int long id, str ck, str ik, str r_alg)
int add_sa(struct mnl_socket* nl_sock, const struct ip_addr *src_addr_param, const struct ip_addr *dest_addr_param, int s_port, int d_port, int long id, str ck, str ik, str r_alg, str r_ealg)
{
char l_msg_buf[MNL_SOCKET_BUFFER_SIZE];
char l_auth_algo_buf[XFRM_TMPLS_BUF_SIZE];
Expand All @@ -121,7 +128,7 @@ int add_sa(struct mnl_socket* nl_sock, const struct ip_addr *src_addr_param, con
l_nlh = mnl_nlmsg_put_header(l_msg_buf);
l_nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
l_nlh->nlmsg_type = XFRM_MSG_NEWSA;
l_nlh->nlmsg_seq = time(NULL);
l_nlh->nlmsg_seq = choose_nlmsg_seq();
l_nlh->nlmsg_pid = id;

// add Security association
Expand Down Expand Up @@ -166,6 +173,8 @@ int add_sa(struct mnl_socket* nl_sock, const struct ip_addr *src_addr_param, con
l_xsainfo->replay_window = 32;

// Add authentication algorithm for this SA
// 3GPP TS 33.203 Annex I
// NOTE: hmac-md5-96 and des-ede3-cbc has been deprecated in Rel12+

// The cast below is performed because alg_key from struct xfrm_algo is char[0]
// The point is to provide a continuous chunk of memory with the key in it
Expand All @@ -189,7 +198,28 @@ int add_sa(struct mnl_socket* nl_sock, const struct ip_addr *src_addr_param, con

// add encription algorithm for this SA
l_enc_algo = (struct xfrm_algo *)l_enc_algo_buf;
// cipher_null, des, des3_ede, aes
strcpy(l_enc_algo->alg_name,"cipher_null");
if (strncasecmp(r_ealg.s,"aes-cbc",r_ealg.len) == 0) {
LM_DBG("Creating security associations: AES\n");
strcpy(l_enc_algo->alg_name,"aes");
l_enc_algo->alg_key_len = ck.len * 4;
string_to_key(l_enc_algo->alg_key, ck);
}
else if (strncasecmp(r_ealg.s,"des-ede3-cbc",r_ealg.len) == 0) {
LM_DBG("Creating security associations: DES, ck.len=%d\n",ck.len);
strcpy(l_enc_algo->alg_name,"des3_ede");
str ck1;
ck1.s = pkg_malloc (128);
strncpy(ck1.s,ck.s,32);
strncat(ck1.s,ck.s,16);
ck1.len=32+16;

l_enc_algo->alg_key_len = ck1.len * 4;
string_to_key(l_enc_algo->alg_key, ck1);

pkg_free(ck1.s);
}
henningw marked this conversation as resolved.
Show resolved Hide resolved

mnl_attr_put(l_nlh, XFRMA_ALG_CRYPT, sizeof(struct xfrm_algo) + l_enc_algo->alg_key_len, l_enc_algo);

Expand Down
2 changes: 1 addition & 1 deletion src/modules/ims_ipsec_pcscf/ipsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ enum ipsec_policy_direction {
struct mnl_socket* init_mnl_socket();
void close_mnl_socket(struct mnl_socket* sock);

int add_sa(struct mnl_socket* nl_sock, const struct ip_addr *src_addr_param, const struct ip_addr *dest_addr_param, int s_port, int d_port, int long id, str ck, str ik, str r_alg);
int add_sa(struct mnl_socket* nl_sock, const struct ip_addr *src_addr_param, const struct ip_addr *dest_addr_param, int s_port, int d_port, int long id, str ck, str ik, str r_alg, str r_ealg);
int remove_sa(struct mnl_socket* nl_sock, str src_addr_param, str dest_addr_param, int s_port, int d_port, int long id, unsigned int af);

int add_policy(struct mnl_socket* mnl_socket, const struct ip_addr *src_addr_param, const struct ip_addr *dest_addr_param, int src_port, int dst_port, int long p_id, enum ipsec_policy_direction dir);
Expand Down