Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
3bab27b6
Commit
3bab27b6
authored
Jan 08, 2003
by
James Morris
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPSEC]: Clean up key manager algorithm handling.
parent
e55ee9fd
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
597 additions
and
221 deletions
+597
-221
include/linux/pfkeyv2.h
include/linux/pfkeyv2.h
+17
-9
include/net/xfrm.h
include/net/xfrm.h
+41
-0
net/ipv4/Makefile
net/ipv4/Makefile
+1
-1
net/ipv4/ah.c
net/ipv4/ah.c
+75
-43
net/ipv4/xfrm_algo.c
net/ipv4/xfrm_algo.c
+348
-0
net/key/af_key.c
net/key/af_key.c
+106
-168
net/netsyms.c
net/netsyms.c
+9
-0
No files found.
include/linux/pfkeyv2.h
View file @
3bab27b6
...
@@ -245,14 +245,22 @@ struct sadb_x_ipsecrequest {
...
@@ -245,14 +245,22 @@ struct sadb_x_ipsecrequest {
#define SADB_AALG_NONE 0
#define SADB_AALG_NONE 0
#define SADB_AALG_MD5HMAC 2
#define SADB_AALG_MD5HMAC 2
#define SADB_AALG_SHA1HMAC 3
#define SADB_AALG_SHA1HMAC 3
#define SADB_AALG_MAX 3
#define SADB_X_AALG_SHA2_256HMAC 5
#define SADB_X_AALG_SHA2_384HMAC 6
#define SADB_X_AALG_SHA2_512HMAC 7
#define SADB_X_AALG_RIPEMD160HMAC 8
#define SADB_X_AALG_NULL 251
/* kame */
#define SADB_AALG_MAX 251
/* Encryption algorithms */
/* Encryption algorithms */
#define SADB_EALG_NONE 0
#define SADB_EALG_NONE 0
#define SADB_EALG_DESCBC 1
#define SADB_EALG_DESCBC 1
#define SADB_EALG_3DESCBC 2
#define SADB_EALG_3DESCBC 2
#define SADB_X_EALG_CASTCBC 6
#define SADB_X_EALG_BLOWFISHCBC 7
#define SADB_EALG_NULL 11
#define SADB_EALG_NULL 11
#define SADB_EALG_MAX 11
#define SADB_X_EALG_AESCBC 12
#define SADB_EALG_MAX 12
/* Extension Header values */
/* Extension Header values */
#define SADB_EXT_RESERVED 0
#define SADB_EXT_RESERVED 0
...
...
include/net/xfrm.h
View file @
3bab27b6
#ifndef _NET_XFRM_H
#define _NET_XFRM_H
#include <linux/xfrm.h>
#include <linux/xfrm.h>
#include <linux/spinlock.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/crypto.h>
#include <linux/crypto.h>
#include <linux/pfkeyv2.h>
#include <net/dst.h>
#include <net/dst.h>
#include <net/route.h>
#include <net/route.h>
#define XFRM_ALIGN8(len) (((len) + 7) & ~7)
extern
struct
semaphore
xfrm_cfg_sem
;
extern
struct
semaphore
xfrm_cfg_sem
;
/* Organization of SPD aka "XFRM rules"
/* Organization of SPD aka "XFRM rules"
...
@@ -347,6 +353,29 @@ static inline void xfrm_sk_free_policy(struct sock *sk)
...
@@ -347,6 +353,29 @@ static inline void xfrm_sk_free_policy(struct sock *sk)
}
}
}
}
/*
* xfrm algorithm information
*/
struct
xfrm_algo_auth_info
{
u16
icv_truncbits
;
u16
icv_fullbits
;
};
struct
xfrm_algo_encr_info
{
u16
blockbits
;
u16
defkeybits
;
};
struct
xfrm_algo_desc
{
char
*
name
;
u8
available
:
1
;
union
{
struct
xfrm_algo_auth_info
auth
;
struct
xfrm_algo_encr_info
encr
;
}
uinfo
;
struct
sadb_alg
desc
;
};
extern
void
xfrm_state_init
(
void
);
extern
void
xfrm_state_init
(
void
);
extern
void
xfrm_input_init
(
void
);
extern
void
xfrm_input_init
(
void
);
extern
int
xfrm_state_walk
(
u8
proto
,
int
(
*
func
)(
struct
xfrm_state
*
,
int
,
void
*
),
void
*
);
extern
int
xfrm_state_walk
(
u8
proto
,
int
(
*
func
)(
struct
xfrm_state
*
,
int
,
void
*
),
void
*
);
...
@@ -385,3 +414,15 @@ extern wait_queue_head_t km_waitq;
...
@@ -385,3 +414,15 @@ extern wait_queue_head_t km_waitq;
extern
void
km_warn_expired
(
struct
xfrm_state
*
x
);
extern
void
km_warn_expired
(
struct
xfrm_state
*
x
);
extern
void
km_expired
(
struct
xfrm_state
*
x
);
extern
void
km_expired
(
struct
xfrm_state
*
x
);
extern
int
km_query
(
struct
xfrm_state
*
x
,
struct
xfrm_tmpl
*
,
struct
xfrm_policy
*
pol
);
extern
int
km_query
(
struct
xfrm_state
*
x
,
struct
xfrm_tmpl
*
,
struct
xfrm_policy
*
pol
);
extern
void
xfrm_probe_algs
(
void
);
extern
int
xfrm_count_auth_supported
(
void
);
extern
int
xfrm_count_enc_supported
(
void
);
extern
struct
xfrm_algo_desc
*
xfrm_aalg_get_byidx
(
unsigned
int
idx
);
extern
struct
xfrm_algo_desc
*
xfrm_ealg_get_byidx
(
unsigned
int
idx
);
extern
struct
xfrm_algo_desc
*
xfrm_aalg_get_byid
(
int
alg_id
);
extern
struct
xfrm_algo_desc
*
xfrm_ealg_get_byid
(
int
alg_id
);
extern
struct
xfrm_algo_desc
*
xfrm_aalg_get_byname
(
char
*
name
);
extern
struct
xfrm_algo_desc
*
xfrm_ealg_get_byname
(
char
*
name
);
#endif
/* _NET_XFRM_H */
net/ipv4/Makefile
View file @
3bab27b6
...
@@ -22,4 +22,4 @@ obj-$(CONFIG_IP_PNP) += ipconfig.o
...
@@ -22,4 +22,4 @@ obj-$(CONFIG_IP_PNP) += ipconfig.o
obj-$(CONFIG_NETFILTER)
+=
netfilter/
obj-$(CONFIG_NETFILTER)
+=
netfilter/
obj-$(CONFIG_XFRM_USER)
+=
xfrm_user.o
obj-$(CONFIG_XFRM_USER)
+=
xfrm_user.o
obj-y
+=
xfrm_policy.o xfrm_state.o xfrm_input.o
obj-y
+=
xfrm_policy.o xfrm_state.o xfrm_input.o
xfrm_algo.o
net/ipv4/ah.c
View file @
3bab27b6
...
@@ -7,26 +7,31 @@
...
@@ -7,26 +7,31 @@
#include <net/icmp.h>
#include <net/icmp.h>
#include <asm/scatterlist.h>
#include <asm/scatterlist.h>
#define AH_HLEN_NOICV 12
typedef
void
(
icv_update_fn_t
)(
struct
crypto_tfm
*
,
struct
scatterlist
*
,
unsigned
int
);
struct
ah_data
struct
ah_data
{
{
u8
*
key
;
u8
*
key
;
int
key_len
;
int
key_len
;
u8
*
work_digest
;
u8
*
work_icv
;
int
digest_len
;
int
icv_full_len
;
int
icv_trunc_len
;
void
(
*
digest
)(
struct
ah_data
*
,
void
(
*
icv
)(
struct
ah_data
*
,
struct
sk_buff
*
skb
,
struct
sk_buff
*
skb
,
u8
*
icv
);
u8
*
digest
);
struct
crypto_tfm
*
tfm
;
struct
crypto_tfm
*
tfm
;
};
};
/* Clear mutable options and find final destination to substitute
/* Clear mutable options and find final destination to substitute
* into IP header for
digest
calculation. Options are already checked
* into IP header for
icv
calculation. Options are already checked
* for validity, so paranoia is not required. */
* for validity, so paranoia is not required. */
int
ip_clear_mutable_options
(
struct
iphdr
*
iph
,
u32
*
daddr
)
static
int
ip_clear_mutable_options
(
struct
iphdr
*
iph
,
u32
*
daddr
)
{
{
unsigned
char
*
optptr
=
(
unsigned
char
*
)(
iph
+
1
);
unsigned
char
*
optptr
=
(
unsigned
char
*
)(
iph
+
1
);
int
l
=
iph
->
ihl
*
4
-
20
;
int
l
=
iph
->
ihl
*
4
-
20
;
...
@@ -66,7 +71,8 @@ int ip_clear_mutable_options(struct iphdr *iph, u32 *daddr)
...
@@ -66,7 +71,8 @@ int ip_clear_mutable_options(struct iphdr *iph, u32 *daddr)
return
0
;
return
0
;
}
}
void
skb_ah_walk
(
const
struct
sk_buff
*
skb
,
struct
crypto_tfm
*
tfm
)
static
void
skb_ah_walk
(
const
struct
sk_buff
*
skb
,
struct
crypto_tfm
*
tfm
,
icv_update_fn_t
icv_update
)
{
{
int
offset
=
0
;
int
offset
=
0
;
int
len
=
skb
->
len
;
int
len
=
skb
->
len
;
...
@@ -83,7 +89,7 @@ void skb_ah_walk(const struct sk_buff *skb, struct crypto_tfm *tfm)
...
@@ -83,7 +89,7 @@ void skb_ah_walk(const struct sk_buff *skb, struct crypto_tfm *tfm)
sg
.
offset
=
(
unsigned
long
)(
skb
->
data
+
offset
)
%
PAGE_SIZE
;
sg
.
offset
=
(
unsigned
long
)(
skb
->
data
+
offset
)
%
PAGE_SIZE
;
sg
.
length
=
copy
;
sg
.
length
=
copy
;
crypto_hmac
_update
(
tfm
,
&
sg
,
1
);
icv
_update
(
tfm
,
&
sg
,
1
);
if
((
len
-=
copy
)
==
0
)
if
((
len
-=
copy
)
==
0
)
return
;
return
;
...
@@ -106,7 +112,7 @@ void skb_ah_walk(const struct sk_buff *skb, struct crypto_tfm *tfm)
...
@@ -106,7 +112,7 @@ void skb_ah_walk(const struct sk_buff *skb, struct crypto_tfm *tfm)
sg
.
offset
=
frag
->
page_offset
+
offset
-
start
;
sg
.
offset
=
frag
->
page_offset
+
offset
-
start
;
sg
.
length
=
copy
;
sg
.
length
=
copy
;
crypto_hmac
_update
(
tfm
,
&
sg
,
1
);
icv
_update
(
tfm
,
&
sg
,
1
);
if
(
!
(
len
-=
copy
))
if
(
!
(
len
-=
copy
))
return
;
return
;
...
@@ -127,7 +133,7 @@ void skb_ah_walk(const struct sk_buff *skb, struct crypto_tfm *tfm)
...
@@ -127,7 +133,7 @@ void skb_ah_walk(const struct sk_buff *skb, struct crypto_tfm *tfm)
if
((
copy
=
end
-
offset
)
>
0
)
{
if
((
copy
=
end
-
offset
)
>
0
)
{
if
(
copy
>
len
)
if
(
copy
>
len
)
copy
=
len
;
copy
=
len
;
skb_ah_walk
(
list
,
tfm
);
skb_ah_walk
(
list
,
tfm
,
icv_update
);
if
((
len
-=
copy
)
==
0
)
if
((
len
-=
copy
)
==
0
)
return
;
return
;
offset
+=
copy
;
offset
+=
copy
;
...
@@ -144,14 +150,14 @@ ah_hmac_digest(struct ah_data *ahp, struct sk_buff *skb, u8 *auth_data)
...
@@ -144,14 +150,14 @@ ah_hmac_digest(struct ah_data *ahp, struct sk_buff *skb, u8 *auth_data)
{
{
struct
crypto_tfm
*
tfm
=
ahp
->
tfm
;
struct
crypto_tfm
*
tfm
=
ahp
->
tfm
;
memset
(
auth_data
,
0
,
ahp
->
digest
_len
);
memset
(
auth_data
,
0
,
ahp
->
icv_trunc
_len
);
crypto_hmac_init
(
tfm
,
ahp
->
key
,
&
ahp
->
key_len
);
crypto_hmac_init
(
tfm
,
ahp
->
key
,
&
ahp
->
key_len
);
skb_ah_walk
(
skb
,
tfm
);
skb_ah_walk
(
skb
,
tfm
,
crypto_hmac_update
);
crypto_hmac_final
(
tfm
,
ahp
->
key
,
&
ahp
->
key_len
,
ahp
->
work_
digest
);
crypto_hmac_final
(
tfm
,
ahp
->
key
,
&
ahp
->
key_len
,
ahp
->
work_
icv
);
memcpy
(
auth_data
,
ahp
->
work_
digest
,
ahp
->
digest
_len
);
memcpy
(
auth_data
,
ahp
->
work_
icv
,
ahp
->
icv_trunc
_len
);
}
}
int
ah_output
(
struct
sk_buff
*
skb
)
static
int
ah_output
(
struct
sk_buff
*
skb
)
{
{
int
err
;
int
err
;
struct
dst_entry
*
dst
=
skb
->
dst
;
struct
dst_entry
*
dst
=
skb
->
dst
;
...
@@ -210,11 +216,13 @@ int ah_output(struct sk_buff *skb)
...
@@ -210,11 +216,13 @@ int ah_output(struct sk_buff *skb)
ah
->
nexthdr
=
iph
->
protocol
;
ah
->
nexthdr
=
iph
->
protocol
;
}
}
ahp
=
x
->
data
;
ahp
=
x
->
data
;
ah
->
hdrlen
=
(((
ahp
->
digest_len
+
12
+
7
)
&~
7
)
>>
2
)
-
2
;
ah
->
hdrlen
=
(
XFRM_ALIGN8
(
ahp
->
icv_trunc_len
+
AH_HLEN_NOICV
)
>>
2
)
-
2
;
ah
->
reserved
=
0
;
ah
->
reserved
=
0
;
ah
->
spi
=
x
->
id
.
spi
;
ah
->
spi
=
x
->
id
.
spi
;
ah
->
seq_no
=
htonl
(
++
x
->
replay
.
oseq
);
ah
->
seq_no
=
htonl
(
++
x
->
replay
.
oseq
);
ahp
->
digest
(
ahp
,
skb
,
ah
->
auth_data
);
ahp
->
icv
(
ahp
,
skb
,
ah
->
auth_data
);
top_iph
->
tos
=
iph
->
tos
;
top_iph
->
tos
=
iph
->
tos
;
top_iph
->
ttl
=
iph
->
ttl
;
top_iph
->
ttl
=
iph
->
ttl
;
if
(
x
->
props
.
mode
)
{
if
(
x
->
props
.
mode
)
{
...
@@ -246,6 +254,7 @@ int ah_output(struct sk_buff *skb)
...
@@ -246,6 +254,7 @@ int ah_output(struct sk_buff *skb)
int
ah_input
(
struct
xfrm_state
*
x
,
struct
sk_buff
*
skb
)
int
ah_input
(
struct
xfrm_state
*
x
,
struct
sk_buff
*
skb
)
{
{
int
ah_hlen
;
struct
iphdr
*
iph
;
struct
iphdr
*
iph
;
struct
ip_auth_hdr
*
ah
;
struct
ip_auth_hdr
*
ah
;
struct
ah_data
*
ahp
;
struct
ah_data
*
ahp
;
...
@@ -255,13 +264,14 @@ int ah_input(struct xfrm_state *x, struct sk_buff *skb)
...
@@ -255,13 +264,14 @@ int ah_input(struct xfrm_state *x, struct sk_buff *skb)
goto
out
;
goto
out
;
ah
=
(
struct
ip_auth_hdr
*
)
skb
->
data
;
ah
=
(
struct
ip_auth_hdr
*
)
skb
->
data
;
ahp
=
x
->
data
;
ahp
=
x
->
data
;
ah_hlen
=
(
ah
->
hdrlen
+
2
)
<<
2
;
if
(((
ah
->
hdrlen
+
2
)
<<
2
)
!=
((
ahp
->
digest_len
+
12
+
7
)
&~
7
))
if
(
ah_hlen
!=
XFRM_ALIGN8
(
ahp
->
icv_full_len
+
AH_HLEN_NOICV
)
&&
ah_hlen
!=
XFRM_ALIGN8
(
ahp
->
icv_trunc_len
+
AH_HLEN_NOICV
))
goto
out
;
goto
out
;
if
(
!
pskb_may_pull
(
skb
,
(
ah
->
hdrlen
+
2
)
<<
2
))
if
(
!
pskb_may_pull
(
skb
,
ah_hlen
))
goto
out
;
goto
out
;
/* We are going to _remove_ AH header to keep sockets happy,
/* We are going to _remove_ AH header to keep sockets happy,
...
@@ -285,17 +295,18 @@ int ah_input(struct xfrm_state *x, struct sk_buff *skb)
...
@@ -285,17 +295,18 @@ int ah_input(struct xfrm_state *x, struct sk_buff *skb)
goto
out
;
goto
out
;
}
}
{
{
u8
auth_data
[
ahp
->
digest_len
];
u8
auth_data
[
ahp
->
icv_trunc_len
];
memcpy
(
auth_data
,
ah
->
auth_data
,
ahp
->
digest_len
);
memcpy
(
auth_data
,
ah
->
auth_data
,
ahp
->
icv_trunc_len
);
skb_push
(
skb
,
skb
->
data
-
skb
->
nh
.
raw
);
skb_push
(
skb
,
skb
->
data
-
skb
->
nh
.
raw
);
ahp
->
digest
(
ahp
,
skb
,
ah
->
auth_data
);
ahp
->
icv
(
ahp
,
skb
,
ah
->
auth_data
);
if
(
memcmp
(
ah
->
auth_data
,
auth_data
,
ahp
->
digest
_len
))
{
if
(
memcmp
(
ah
->
auth_data
,
auth_data
,
ahp
->
icv_trunc
_len
))
{
x
->
stats
.
integrity_failed
++
;
x
->
stats
.
integrity_failed
++
;
goto
out
;
goto
out
;
}
}
}
}
((
struct
iphdr
*
)
work_buf
)
->
protocol
=
ah
->
nexthdr
;
((
struct
iphdr
*
)
work_buf
)
->
protocol
=
ah
->
nexthdr
;
skb
->
nh
.
raw
=
skb_pull
(
skb
,
(
ah
->
hdrlen
+
2
)
<<
2
);
skb
->
nh
.
raw
=
skb_pull
(
skb
,
ah_hlen
);
memcpy
(
skb
->
nh
.
raw
,
work_buf
,
iph
->
ihl
*
4
);
memcpy
(
skb
->
nh
.
raw
,
work_buf
,
iph
->
ihl
*
4
);
skb
->
nh
.
iph
->
tot_len
=
htons
(
skb
->
len
);
skb
->
nh
.
iph
->
tot_len
=
htons
(
skb
->
len
);
skb_pull
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
);
skb_pull
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
);
...
@@ -325,12 +336,13 @@ void ah4_err(struct sk_buff *skb, u32 info)
...
@@ -325,12 +336,13 @@ void ah4_err(struct sk_buff *skb, u32 info)
xfrm_state_put
(
x
);
xfrm_state_put
(
x
);
}
}
int
ah_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
static
int
ah_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
{
{
struct
ah_data
*
ahp
=
NULL
;
struct
ah_data
*
ahp
=
NULL
;
struct
xfrm_algo_desc
*
aalg_desc
;
if
(
x
->
aalg
==
NULL
||
x
->
aalg
->
alg_key_len
==
0
||
/* null auth can use a zero length key */
x
->
aalg
->
alg_key_len
>
512
)
if
(
x
->
aalg
->
alg_key_len
>
512
)
goto
error
;
goto
error
;
ahp
=
kmalloc
(
sizeof
(
*
ahp
),
GFP_KERNEL
);
ahp
=
kmalloc
(
sizeof
(
*
ahp
),
GFP_KERNEL
);
...
@@ -344,13 +356,33 @@ int ah_init_state(struct xfrm_state *x, void *args)
...
@@ -344,13 +356,33 @@ int ah_init_state(struct xfrm_state *x, void *args)
ahp
->
tfm
=
crypto_alloc_tfm
(
x
->
aalg
->
alg_name
,
0
);
ahp
->
tfm
=
crypto_alloc_tfm
(
x
->
aalg
->
alg_name
,
0
);
if
(
!
ahp
->
tfm
)
if
(
!
ahp
->
tfm
)
goto
error
;
goto
error
;
ahp
->
digest
=
ah_hmac_digest
;
ahp
->
icv
=
ah_hmac_digest
;
ahp
->
digest_len
=
12
;
ahp
->
work_digest
=
kmalloc
(
crypto_tfm_alg_digestsize
(
ahp
->
tfm
),
/*
GFP_KERNEL
);
* Lookup the algorithm description maintained by pfkey,
if
(
!
ahp
->
work_digest
)
* verify crypto transform properties, and store information
* we need for AH processing. This lookup cannot fail here
* after a successful crypto_alloc_tfm().
*/
aalg_desc
=
xfrm_aalg_get_byname
(
x
->
aalg
->
alg_name
);
BUG_ON
(
!
aalg_desc
);
if
(
aalg_desc
->
uinfo
.
auth
.
icv_fullbits
/
8
!=
crypto_tfm_alg_digestsize
(
ahp
->
tfm
))
{
printk
(
KERN_INFO
"AH: %s digestsize %u != %hu
\n
"
,
x
->
aalg
->
alg_name
,
crypto_tfm_alg_digestsize
(
ahp
->
tfm
),
aalg_desc
->
uinfo
.
auth
.
icv_fullbits
/
8
);
goto
error
;
goto
error
;
x
->
props
.
header_len
=
(
12
+
ahp
->
digest_len
+
7
)
&~
7
;
}
ahp
->
icv_full_len
=
aalg_desc
->
uinfo
.
auth
.
icv_fullbits
/
8
;
ahp
->
icv_trunc_len
=
aalg_desc
->
uinfo
.
auth
.
icv_truncbits
/
8
;
ahp
->
work_icv
=
kmalloc
(
ahp
->
icv_full_len
,
GFP_KERNEL
);
if
(
!
ahp
->
work_icv
)
goto
error
;
x
->
props
.
header_len
=
XFRM_ALIGN8
(
ahp
->
icv_trunc_len
+
AH_HLEN_NOICV
);
if
(
x
->
props
.
mode
)
if
(
x
->
props
.
mode
)
x
->
props
.
header_len
+=
20
;
x
->
props
.
header_len
+=
20
;
x
->
data
=
ahp
;
x
->
data
=
ahp
;
...
@@ -359,8 +391,8 @@ int ah_init_state(struct xfrm_state *x, void *args)
...
@@ -359,8 +391,8 @@ int ah_init_state(struct xfrm_state *x, void *args)
error:
error:
if
(
ahp
)
{
if
(
ahp
)
{
if
(
ahp
->
work_
digest
)
if
(
ahp
->
work_
icv
)
kfree
(
ahp
->
work_
digest
);
kfree
(
ahp
->
work_
icv
);
if
(
ahp
->
tfm
)
if
(
ahp
->
tfm
)
crypto_free_tfm
(
ahp
->
tfm
);
crypto_free_tfm
(
ahp
->
tfm
);
kfree
(
ahp
);
kfree
(
ahp
);
...
@@ -368,13 +400,13 @@ int ah_init_state(struct xfrm_state *x, void *args)
...
@@ -368,13 +400,13 @@ int ah_init_state(struct xfrm_state *x, void *args)
return
-
EINVAL
;
return
-
EINVAL
;
}
}
void
ah_destroy
(
struct
xfrm_state
*
x
)
static
void
ah_destroy
(
struct
xfrm_state
*
x
)
{
{
struct
ah_data
*
ahp
=
x
->
data
;
struct
ah_data
*
ahp
=
x
->
data
;
if
(
ahp
->
work_
digest
)
{
if
(
ahp
->
work_
icv
)
{
kfree
(
ahp
->
work_
digest
);
kfree
(
ahp
->
work_
icv
);
ahp
->
work_
digest
=
NULL
;
ahp
->
work_
icv
=
NULL
;
}
}
if
(
ahp
->
tfm
)
{
if
(
ahp
->
tfm
)
{
crypto_free_tfm
(
ahp
->
tfm
);
crypto_free_tfm
(
ahp
->
tfm
);
...
@@ -399,7 +431,7 @@ static struct inet_protocol ah4_protocol = {
...
@@ -399,7 +431,7 @@ static struct inet_protocol ah4_protocol = {
.
no_policy
=
1
,
.
no_policy
=
1
,
};
};
int
__init
ah4_init
(
void
)
static
int
__init
ah4_init
(
void
)
{
{
SET_MODULE_OWNER
(
&
ah_type
);
SET_MODULE_OWNER
(
&
ah_type
);
if
(
xfrm_register_type
(
&
ah_type
)
<
0
)
{
if
(
xfrm_register_type
(
&
ah_type
)
<
0
)
{
...
...
net/ipv4/xfrm_algo.c
0 → 100644
View file @
3bab27b6
/*
* xfrm algorithm interface
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*/
#include <linux/kernel.h>
#include <linux/pfkeyv2.h>
#include <net/xfrm.h>
/*
* Algorithms supported by IPsec. These entries contain properties which
* are used in key negotiation and xfrm processing, and are used to verify
* that instantiated crypto transforms have correct parameters for IPsec
* purposes.
*/
static
struct
xfrm_algo_desc
aalg_list
[]
=
{
{
.
name
=
"digest_null"
,
.
uinfo
=
{
.
auth
=
{
.
icv_truncbits
=
0
,
.
icv_fullbits
=
0
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_X_AALG_NULL
,
.
sadb_alg_ivlen
=
0
,
.
sadb_alg_minbits
=
0
,
.
sadb_alg_maxbits
=
0
}
},
{
.
name
=
"md5"
,
.
uinfo
=
{
.
auth
=
{
.
icv_truncbits
=
96
,
.
icv_fullbits
=
128
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_AALG_MD5HMAC
,
.
sadb_alg_ivlen
=
0
,
.
sadb_alg_minbits
=
128
,
.
sadb_alg_maxbits
=
128
}
},
{
.
name
=
"sha1"
,
.
uinfo
=
{
.
auth
=
{
.
icv_truncbits
=
96
,
.
icv_fullbits
=
160
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_AALG_SHA1HMAC
,
.
sadb_alg_ivlen
=
0
,
.
sadb_alg_minbits
=
160
,
.
sadb_alg_maxbits
=
160
}
},
{
.
name
=
"sha256"
,
.
uinfo
=
{
.
auth
=
{
.
icv_truncbits
=
128
,
.
icv_fullbits
=
256
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_X_AALG_SHA2_256HMAC
,
.
sadb_alg_ivlen
=
0
,
.
sadb_alg_minbits
=
256
,
.
sadb_alg_maxbits
=
256
}
},
{
.
name
=
"ripemd160"
,
.
uinfo
=
{
.
auth
=
{
.
icv_truncbits
=
96
,
.
icv_fullbits
=
160
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_X_AALG_RIPEMD160HMAC
,
.
sadb_alg_ivlen
=
0
,
.
sadb_alg_minbits
=
160
,
.
sadb_alg_maxbits
=
160
}
},
};
static
struct
xfrm_algo_desc
ealg_list
[]
=
{
{
.
name
=
"cipher_null"
,
.
uinfo
=
{
.
encr
=
{
.
blockbits
=
8
,
.
defkeybits
=
0
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_EALG_NULL
,
.
sadb_alg_ivlen
=
0
,
.
sadb_alg_minbits
=
0
,
.
sadb_alg_maxbits
=
0
}
},
{
.
name
=
"des"
,
.
uinfo
=
{
.
encr
=
{
.
blockbits
=
64
,
.
defkeybits
=
64
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_EALG_DESCBC
,
.
sadb_alg_ivlen
=
8
,
.
sadb_alg_minbits
=
64
,
.
sadb_alg_maxbits
=
64
}
},
{
.
name
=
"des3_ede"
,
.
uinfo
=
{
.
encr
=
{
.
blockbits
=
64
,
.
defkeybits
=
192
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_EALG_3DESCBC
,
.
sadb_alg_ivlen
=
8
,
.
sadb_alg_minbits
=
192
,
.
sadb_alg_maxbits
=
192
}
},
{
.
name
=
"cast128"
,
.
uinfo
=
{
.
encr
=
{
.
blockbits
=
64
,
.
defkeybits
=
128
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_X_EALG_CASTCBC
,
.
sadb_alg_ivlen
=
8
,
.
sadb_alg_minbits
=
40
,
.
sadb_alg_maxbits
=
128
}
},
{
.
name
=
"blowfish"
,
.
uinfo
=
{
.
encr
=
{
.
blockbits
=
64
,
.
defkeybits
=
128
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_X_EALG_BLOWFISHCBC
,
.
sadb_alg_ivlen
=
8
,
.
sadb_alg_minbits
=
40
,
.
sadb_alg_maxbits
=
448
}
},
{
.
name
=
"aes"
,
.
uinfo
=
{
.
encr
=
{
.
blockbits
=
128
,
.
defkeybits
=
128
,
}
},
.
desc
=
{
.
sadb_alg_id
=
SADB_X_EALG_AESCBC
,
.
sadb_alg_ivlen
=
8
,
.
sadb_alg_minbits
=
128
,
.
sadb_alg_maxbits
=
256
}
},
};
static
inline
int
aalg_entries
(
void
)
{
return
sizeof
(
aalg_list
)
/
sizeof
(
aalg_list
[
0
]);
}
static
inline
int
ealg_entries
(
void
)
{
return
sizeof
(
ealg_list
)
/
sizeof
(
ealg_list
[
0
]);
}
struct
xfrm_algo_desc
*
xfrm_aalg_get_byid
(
int
alg_id
)
{
int
i
;
for
(
i
=
0
;
i
<
aalg_entries
();
i
++
)
{
if
(
aalg_list
[
i
].
desc
.
sadb_alg_id
==
alg_id
)
{
if
(
aalg_list
[
i
].
available
)
return
&
aalg_list
[
i
];
else
break
;
}
}
return
NULL
;
}
struct
xfrm_algo_desc
*
xfrm_ealg_get_byid
(
int
alg_id
)
{
int
i
;
for
(
i
=
0
;
i
<
ealg_entries
();
i
++
)
{
if
(
ealg_list
[
i
].
desc
.
sadb_alg_id
==
alg_id
)
{
if
(
ealg_list
[
i
].
available
)
return
&
ealg_list
[
i
];
else
break
;
}
}
return
NULL
;
}
struct
xfrm_algo_desc
*
xfrm_aalg_get_byname
(
char
*
name
)
{
int
i
;
if
(
!
name
)
return
NULL
;
for
(
i
=
0
;
i
<
aalg_entries
();
i
++
)
{
if
(
strcmp
(
name
,
aalg_list
[
i
].
name
)
==
0
)
{
if
(
aalg_list
[
i
].
available
)
return
&
aalg_list
[
i
];
else
break
;
}
}
return
NULL
;
}
struct
xfrm_algo_desc
*
xfrm_ealg_get_byname
(
char
*
name
)
{
int
i
;
if
(
!
name
)
return
NULL
;
for
(
i
=
0
;
i
<
ealg_entries
();
i
++
)
{
if
(
strcmp
(
name
,
ealg_list
[
i
].
name
)
==
0
)
{
if
(
ealg_list
[
i
].
available
)
return
&
ealg_list
[
i
];
else
break
;
}
}
return
NULL
;
}
struct
xfrm_algo_desc
*
xfrm_aalg_get_byidx
(
unsigned
int
idx
)
{
if
(
idx
>=
aalg_entries
())
return
NULL
;
return
&
aalg_list
[
idx
];
}
struct
xfrm_algo_desc
*
xfrm_ealg_get_byidx
(
unsigned
int
idx
)
{
if
(
idx
>=
ealg_entries
())
return
NULL
;
return
&
ealg_list
[
idx
];
}
/*
* Probe for the availability of crypto algorithms, and set the available
* flag for any algorithms found on the system. This is typically called by
* pfkey during userspace SA add, update or register.
*/
void
xfrm_probe_algs
(
void
)
{
int
i
,
status
;
BUG_ON
(
in_softirq
());
for
(
i
=
0
;
i
<
aalg_entries
();
i
++
)
{
status
=
crypto_alg_available
(
aalg_list
[
i
].
name
,
0
);
if
(
aalg_list
[
i
].
available
!=
status
)
aalg_list
[
i
].
available
=
status
;
}
for
(
i
=
0
;
i
<
ealg_entries
();
i
++
)
{
status
=
crypto_alg_available
(
ealg_list
[
i
].
name
,
0
);
if
(
ealg_list
[
i
].
available
!=
status
)
ealg_list
[
i
].
available
=
status
;
}
}
int
xfrm_count_auth_supported
(
void
)
{
int
i
,
n
;
for
(
i
=
0
,
n
=
0
;
i
<
aalg_entries
();
i
++
)
if
(
aalg_list
[
i
].
available
)
n
++
;
return
n
;
}
int
xfrm_count_enc_supported
(
void
)
{
int
i
,
n
;
for
(
i
=
0
,
n
=
0
;
i
<
ealg_entries
();
i
++
)
if
(
ealg_list
[
i
].
available
)
n
++
;
return
n
;
}
net/key/af_key.c
View file @
3bab27b6
...
@@ -553,118 +553,6 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **
...
@@ -553,118 +553,6 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **
return
x
;
return
x
;
}
}
/* Table of algos supported by pfkeyv2 interface. */
struct
algo_desc
{
char
*
id
;
struct
sadb_alg
desc
;
};
struct
algo_desc
aalg_list
[]
=
{
{
.
id
=
NULL
,
.
desc
=
{
.
sadb_alg_id
=
SADB_AALG_NONE
,
.
sadb_alg_ivlen
=
0
,
.
sadb_alg_minbits
=
0
,
.
sadb_alg_maxbits
=
0
}
},
{
.
id
=
"md5"
,
.
desc
=
{
.
sadb_alg_id
=
SADB_AALG_MD5HMAC
,
.
sadb_alg_ivlen
=
0
,
.
sadb_alg_minbits
=
128
,
.
sadb_alg_maxbits
=
128
}
},
{
.
id
=
"sha1"
,
.
desc
=
{
.
sadb_alg_id
=
SADB_AALG_SHA1HMAC
,
.
sadb_alg_ivlen
=
0
,
.
sadb_alg_minbits
=
160
,
.
sadb_alg_maxbits
=
160
}
}
};
struct
algo_desc
ealg_list
[]
=
{
{
.
id
=
NULL
,
.
desc
=
{
.
sadb_alg_id
=
SADB_EALG_NONE
,
.
sadb_alg_ivlen
=
0
,
.
sadb_alg_minbits
=
0
,
.
sadb_alg_maxbits
=
2048
}
},
{
.
id
=
"des"
,
.
desc
=
{
.
sadb_alg_id
=
SADB_EALG_DESCBC
,
.
sadb_alg_ivlen
=
8
,
.
sadb_alg_minbits
=
64
,
.
sadb_alg_maxbits
=
64
}
},
{
.
id
=
"des3_ede"
,
.
desc
=
{
.
sadb_alg_id
=
SADB_EALG_3DESCBC
,
.
sadb_alg_ivlen
=
8
,
.
sadb_alg_minbits
=
192
,
.
sadb_alg_maxbits
=
192
}
}
};
static
struct
algo_desc
*
aalg_get_byid
(
int
alg_id
)
{
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
aalg_list
)
/
sizeof
(
aalg_list
[
0
]);
i
++
)
{
if
(
aalg_list
[
i
].
desc
.
sadb_alg_id
==
alg_id
)
return
&
aalg_list
[
i
];
}
return
NULL
;
}
static
struct
algo_desc
*
ealg_get_byid
(
int
alg_id
)
{
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
ealg_list
)
/
sizeof
(
ealg_list
[
0
]);
i
++
)
{
if
(
ealg_list
[
i
].
desc
.
sadb_alg_id
==
alg_id
)
return
&
ealg_list
[
i
];
}
return
NULL
;
}
static
struct
algo_desc
*
aalg_get_byname
(
char
*
name
)
{
int
i
;
if
(
!
name
)
return
NULL
;
for
(
i
=
1
;
i
<
sizeof
(
aalg_list
)
/
sizeof
(
aalg_list
[
0
]);
i
++
)
{
if
(
strcmp
(
name
,
aalg_list
[
i
].
id
)
==
0
)
return
&
aalg_list
[
i
];
}
return
NULL
;
}
static
struct
algo_desc
*
ealg_get_byname
(
char
*
name
)
{
int
i
;
if
(
!
name
)
return
NULL
;
for
(
i
=
1
;
i
<
sizeof
(
ealg_list
)
/
sizeof
(
ealg_list
[
0
]);
i
++
)
{
if
(
strcmp
(
name
,
ealg_list
[
i
].
id
)
==
0
)
return
&
ealg_list
[
i
];
}
return
NULL
;
}
#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
static
struct
sk_buff
*
pfkey_xfrm_state2msg
(
struct
xfrm_state
*
x
,
int
add_keys
,
int
hsc
)
static
struct
sk_buff
*
pfkey_xfrm_state2msg
(
struct
xfrm_state
*
x
,
int
add_keys
,
int
hsc
)
{
{
...
@@ -730,12 +618,12 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
...
@@ -730,12 +618,12 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
sa
->
sadb_sa_state
=
SADB_SASTATE_DEAD
;
sa
->
sadb_sa_state
=
SADB_SASTATE_DEAD
;
sa
->
sadb_sa_auth
=
0
;
sa
->
sadb_sa_auth
=
0
;
if
(
x
->
aalg
)
{
if
(
x
->
aalg
)
{
struct
algo_desc
*
a
=
aalg_get_byname
(
x
->
aalg
->
alg_name
);
struct
xfrm_algo_desc
*
a
=
xfrm_
aalg_get_byname
(
x
->
aalg
->
alg_name
);
sa
->
sadb_sa_auth
=
a
?
a
->
desc
.
sadb_alg_id
:
0
;
sa
->
sadb_sa_auth
=
a
?
a
->
desc
.
sadb_alg_id
:
0
;
}
}
sa
->
sadb_sa_encrypt
=
0
;
sa
->
sadb_sa_encrypt
=
0
;
if
(
x
->
ealg
)
{
if
(
x
->
ealg
)
{
struct
algo_desc
*
a
=
ealg_get_byname
(
x
->
ealg
->
alg_name
);
struct
xfrm_algo_desc
*
a
=
xfrm_
ealg_get_byname
(
x
->
ealg
->
alg_name
);
sa
->
sadb_sa_encrypt
=
a
?
a
->
desc
.
sadb_alg_id
:
0
;
sa
->
sadb_sa_encrypt
=
a
?
a
->
desc
.
sadb_alg_id
:
0
;
}
}
sa
->
sadb_sa_flags
=
0
;
sa
->
sadb_sa_flags
=
0
;
...
@@ -938,7 +826,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
...
@@ -938,7 +826,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
key
=
(
struct
sadb_key
*
)
ext_hdrs
[
SADB_EXT_KEY_AUTH
-
1
];
key
=
(
struct
sadb_key
*
)
ext_hdrs
[
SADB_EXT_KEY_AUTH
-
1
];
if
(
sa
->
sadb_sa_auth
)
{
if
(
sa
->
sadb_sa_auth
)
{
int
keysize
=
0
;
int
keysize
=
0
;
struct
algo_desc
*
a
=
aalg_get_byid
(
sa
->
sadb_sa_auth
);
struct
xfrm_algo_desc
*
a
=
xfrm_
aalg_get_byid
(
sa
->
sadb_sa_auth
);
if
(
!
a
)
if
(
!
a
)
goto
out
;
goto
out
;
if
(
key
)
if
(
key
)
...
@@ -946,7 +834,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
...
@@ -946,7 +834,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
x
->
aalg
=
kmalloc
(
sizeof
(
*
x
->
aalg
)
+
keysize
,
GFP_KERNEL
);
x
->
aalg
=
kmalloc
(
sizeof
(
*
x
->
aalg
)
+
keysize
,
GFP_KERNEL
);
if
(
!
x
->
aalg
)
if
(
!
x
->
aalg
)
goto
out
;
goto
out
;
strcpy
(
x
->
aalg
->
alg_name
,
a
->
id
);
strcpy
(
x
->
aalg
->
alg_name
,
a
->
name
);
x
->
aalg
->
alg_key_len
=
0
;
x
->
aalg
->
alg_key_len
=
0
;
if
(
key
)
{
if
(
key
)
{
x
->
aalg
->
alg_key_len
=
key
->
sadb_key_bits
;
x
->
aalg
->
alg_key_len
=
key
->
sadb_key_bits
;
...
@@ -958,7 +846,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
...
@@ -958,7 +846,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
key
=
(
struct
sadb_key
*
)
ext_hdrs
[
SADB_EXT_KEY_ENCRYPT
-
1
];
key
=
(
struct
sadb_key
*
)
ext_hdrs
[
SADB_EXT_KEY_ENCRYPT
-
1
];
if
(
sa
->
sadb_sa_encrypt
)
{
if
(
sa
->
sadb_sa_encrypt
)
{
int
keysize
=
0
;
int
keysize
=
0
;
struct
algo_desc
*
a
=
ealg_get_byid
(
sa
->
sadb_sa_encrypt
);
struct
xfrm_algo_desc
*
a
=
xfrm_
ealg_get_byid
(
sa
->
sadb_sa_encrypt
);
if
(
!
a
)
if
(
!
a
)
goto
out
;
goto
out
;
if
(
key
)
if
(
key
)
...
@@ -966,7 +854,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
...
@@ -966,7 +854,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
x
->
ealg
=
kmalloc
(
sizeof
(
*
x
->
ealg
)
+
keysize
,
GFP_KERNEL
);
x
->
ealg
=
kmalloc
(
sizeof
(
*
x
->
ealg
)
+
keysize
,
GFP_KERNEL
);
if
(
!
x
->
ealg
)
if
(
!
x
->
ealg
)
goto
out
;
goto
out
;
strcpy
(
x
->
ealg
->
alg_name
,
a
->
id
);
strcpy
(
x
->
ealg
->
alg_name
,
a
->
name
);
x
->
ealg
->
alg_key_len
=
0
;
x
->
ealg
->
alg_key_len
=
0
;
if
(
key
)
{
if
(
key
)
{
x
->
ealg
->
alg_key_len
=
key
->
sadb_key_bits
;
x
->
ealg
->
alg_key_len
=
key
->
sadb_key_bits
;
...
@@ -1131,6 +1019,8 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
...
@@ -1131,6 +1019,8 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
struct
xfrm_state
*
x
;
struct
xfrm_state
*
x
;
struct
xfrm_state
*
x1
;
struct
xfrm_state
*
x1
;
xfrm_probe_algs
();
x
=
pfkey_msg2xfrm_state
(
hdr
,
ext_hdrs
);
x
=
pfkey_msg2xfrm_state
(
hdr
,
ext_hdrs
);
if
(
IS_ERR
(
x
))
if
(
IS_ERR
(
x
))
return
PTR_ERR
(
x
);
return
PTR_ERR
(
x
);
...
@@ -1238,17 +1128,21 @@ static struct sk_buff *compose_sadb_supported(struct sadb_msg *orig, int allocat
...
@@ -1238,17 +1128,21 @@ static struct sk_buff *compose_sadb_supported(struct sadb_msg *orig, int allocat
{
{
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
struct
sadb_msg
*
hdr
;
struct
sadb_msg
*
hdr
;
int
len
,
ah_len
,
esp_len
,
i
;
int
len
,
auth_len
,
enc_len
,
i
;
ah_len
=
sizeof
(
aalg_list
)
/
sizeof
(
aalg_list
[
0
])
-
1
;
auth_len
=
xfrm_count_auth_supported
();
ah_len
*=
sizeof
(
struct
sadb_alg
);
if
(
auth_len
)
{
esp_len
=
sizeof
(
ealg_list
)
/
sizeof
(
ealg_list
[
0
])
-
1
;
auth_len
*=
sizeof
(
struct
sadb_alg
);
esp_len
*=
sizeof
(
struct
sadb_alg
);
auth_len
+=
sizeof
(
struct
sadb_supported
);
if
(
ah_len
)
}
ah_len
+=
sizeof
(
struct
sadb_supported
);
if
(
esp_len
)
enc_len
=
xfrm_count_enc_supported
();
esp_len
+=
sizeof
(
struct
sadb_supported
);
if
(
enc_len
)
{
len
=
esp_len
+
ah_len
+
sizeof
(
struct
sadb_msg
);
enc_len
*=
sizeof
(
struct
sadb_alg
);
enc_len
+=
sizeof
(
struct
sadb_supported
);
}
len
=
enc_len
+
auth_len
+
sizeof
(
struct
sadb_msg
);
skb
=
alloc_skb
(
len
+
16
,
allocation
);
skb
=
alloc_skb
(
len
+
16
,
allocation
);
if
(
!
skb
)
if
(
!
skb
)
...
@@ -1259,32 +1153,42 @@ static struct sk_buff *compose_sadb_supported(struct sadb_msg *orig, int allocat
...
@@ -1259,32 +1153,42 @@ static struct sk_buff *compose_sadb_supported(struct sadb_msg *orig, int allocat
hdr
->
sadb_msg_errno
=
0
;
hdr
->
sadb_msg_errno
=
0
;
hdr
->
sadb_msg_len
=
len
/
sizeof
(
uint64_t
);
hdr
->
sadb_msg_len
=
len
/
sizeof
(
uint64_t
);
if
(
ah_len
)
{
if
(
a
ut
h_len
)
{
struct
sadb_supported
*
sp
;
struct
sadb_supported
*
sp
;
struct
sadb_alg
*
ap
;
struct
sadb_alg
*
ap
;
sp
=
(
struct
sadb_supported
*
)
skb_put
(
skb
,
ah_len
);
sp
=
(
struct
sadb_supported
*
)
skb_put
(
skb
,
a
ut
h_len
);
ap
=
(
struct
sadb_alg
*
)
(
sp
+
1
);
ap
=
(
struct
sadb_alg
*
)
(
sp
+
1
);
sp
->
sadb_supported_len
=
ah_len
/
sizeof
(
uint64_t
);
sp
->
sadb_supported_len
=
a
ut
h_len
/
sizeof
(
uint64_t
);
sp
->
sadb_supported_exttype
=
SADB_EXT_SUPPORTED_AUTH
;
sp
->
sadb_supported_exttype
=
SADB_EXT_SUPPORTED_AUTH
;
for
(
i
=
1
;
i
<
sizeof
(
aalg_list
)
/
sizeof
(
aalg_list
[
0
]);
i
++
)
for
(
i
=
0
;
;
i
++
)
{
*
ap
++
=
aalg_list
[
i
].
desc
;
struct
xfrm_algo_desc
*
aalg
=
xfrm_aalg_get_byidx
(
i
);
if
(
!
aalg
)
break
;
if
(
aalg
->
available
)
*
ap
++
=
aalg
->
desc
;
}
}
}
if
(
e
sp
_len
)
{
if
(
e
nc
_len
)
{
struct
sadb_supported
*
sp
;
struct
sadb_supported
*
sp
;
struct
sadb_alg
*
ap
;
struct
sadb_alg
*
ap
;
sp
=
(
struct
sadb_supported
*
)
skb_put
(
skb
,
e
sp
_len
);
sp
=
(
struct
sadb_supported
*
)
skb_put
(
skb
,
e
nc
_len
);
ap
=
(
struct
sadb_alg
*
)
(
sp
+
1
);
ap
=
(
struct
sadb_alg
*
)
(
sp
+
1
);
sp
->
sadb_supported_len
=
e
sp
_len
/
sizeof
(
uint64_t
);
sp
->
sadb_supported_len
=
e
nc
_len
/
sizeof
(
uint64_t
);
sp
->
sadb_supported_exttype
=
SADB_EXT_SUPPORTED_ENCRYPT
;
sp
->
sadb_supported_exttype
=
SADB_EXT_SUPPORTED_ENCRYPT
;
for
(
i
=
1
;
i
<
sizeof
(
ealg_list
)
/
sizeof
(
ealg_list
[
0
]);
i
++
)
for
(
i
=
0
;
;
i
++
)
{
*
ap
++
=
ealg_list
[
i
].
desc
;
struct
xfrm_algo_desc
*
ealg
=
xfrm_ealg_get_byidx
(
i
);
if
(
!
ealg
)
break
;
if
(
ealg
->
available
)
*
ap
++
=
ealg
->
desc
;
}
}
}
out_put_algs:
out_put_algs:
...
@@ -1305,6 +1209,8 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg
...
@@ -1305,6 +1209,8 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg
pfk
->
registered
|=
(
1
<<
hdr
->
sadb_msg_satype
);
pfk
->
registered
|=
(
1
<<
hdr
->
sadb_msg_satype
);
}
}
xfrm_probe_algs
();
supp_skb
=
compose_sadb_supported
(
hdr
,
GFP_KERNEL
);
supp_skb
=
compose_sadb_supported
(
hdr
,
GFP_KERNEL
);
if
(
!
supp_skb
)
{
if
(
!
supp_skb
)
{
if
(
hdr
->
sadb_msg_satype
!=
SADB_SATYPE_UNSPEC
)
if
(
hdr
->
sadb_msg_satype
!=
SADB_SATYPE_UNSPEC
)
...
@@ -1955,35 +1861,55 @@ static struct sadb_msg *pfkey_get_base_msg(struct sk_buff *skb, int *errp)
...
@@ -1955,35 +1861,55 @@ static struct sadb_msg *pfkey_get_base_msg(struct sk_buff *skb, int *errp)
return
hdr
;
return
hdr
;
}
}
int
count_ah_combs
(
struct
xfrm_tmpl
*
t
)
static
inline
int
aalg_tmpl_set
(
struct
xfrm_tmpl
*
t
,
struct
xfrm_algo_desc
*
d
)
{
{
int
sz
=
0
;
return
t
->
aalgos
&
(
1
<<
d
->
desc
.
sadb_alg_id
)
;
int
i
;
}
for
(
i
=
1
;
i
<
sizeof
(
aalg_list
)
/
sizeof
(
aalg_list
[
0
]);
i
++
)
{
static
inline
int
ealg_tmpl_set
(
struct
xfrm_tmpl
*
t
,
struct
xfrm_algo_desc
*
d
)
if
(
t
->
aalgos
&
(
1
<<
aalg_list
[
i
].
desc
.
sadb_alg_id
))
{
return
t
->
ealgos
&
(
1
<<
d
->
desc
.
sadb_alg_id
);
}
static
int
count_ah_combs
(
struct
xfrm_tmpl
*
t
)
{
int
i
,
sz
=
0
;
for
(
i
=
0
;
;
i
++
)
{
struct
xfrm_algo_desc
*
aalg
=
xfrm_aalg_get_byidx
(
i
);
if
(
!
aalg
)
break
;
if
(
aalg_tmpl_set
(
t
,
aalg
)
&&
aalg
->
available
)
sz
+=
sizeof
(
struct
sadb_comb
);
sz
+=
sizeof
(
struct
sadb_comb
);
}
}
return
sz
+
sizeof
(
struct
sadb_prop
);
return
sz
+
sizeof
(
struct
sadb_prop
);
}
}
int
count_esp_combs
(
struct
xfrm_tmpl
*
t
)
static
int
count_esp_combs
(
struct
xfrm_tmpl
*
t
)
{
{
int
sz
=
0
;
int
i
,
k
,
sz
=
0
;
int
i
,
k
;
for
(
i
=
0
;
;
i
++
)
{
struct
xfrm_algo_desc
*
ealg
=
xfrm_ealg_get_byidx
(
i
);
if
(
!
ealg
)
break
;
for
(
i
=
1
;
i
<
sizeof
(
ealg_list
)
/
sizeof
(
ealg_list
[
0
]);
i
++
)
{
if
(
!
(
ealg_tmpl_set
(
t
,
ealg
)
&&
ealg
->
available
))
if
(
!
(
t
->
ealgos
&
(
1
<<
ealg_list
[
i
].
desc
.
sadb_alg_id
)))
continue
;
continue
;
for
(
k
=
1
;
k
<
sizeof
(
aalg_list
)
/
sizeof
(
aalg_list
[
0
]);
k
++
)
{
if
(
t
->
aalgos
&
(
1
<<
aalg_list
[
i
].
desc
.
sadb_alg_id
))
for
(
k
=
1
;
;
k
++
)
{
struct
xfrm_algo_desc
*
aalg
=
xfrm_aalg_get_byidx
(
k
);
if
(
!
aalg
)
break
;
if
(
aalg_tmpl_set
(
t
,
aalg
)
&&
aalg
->
available
)
sz
+=
sizeof
(
struct
sadb_comb
);
sz
+=
sizeof
(
struct
sadb_comb
);
}
}
}
}
return
sz
+
sizeof
(
struct
sadb_prop
);
return
sz
+
sizeof
(
struct
sadb_prop
);
}
}
void
dump_ah_combs
(
struct
sk_buff
*
skb
,
struct
xfrm_tmpl
*
t
)
static
void
dump_ah_combs
(
struct
sk_buff
*
skb
,
struct
xfrm_tmpl
*
t
)
{
{
struct
sadb_prop
*
p
;
struct
sadb_prop
*
p
;
int
i
;
int
i
;
...
@@ -1993,15 +1919,19 @@ void dump_ah_combs(struct sk_buff *skb, struct xfrm_tmpl *t)
...
@@ -1993,15 +1919,19 @@ void dump_ah_combs(struct sk_buff *skb, struct xfrm_tmpl *t)
p
->
sadb_prop_exttype
=
SADB_EXT_PROPOSAL
;
p
->
sadb_prop_exttype
=
SADB_EXT_PROPOSAL
;
p
->
sadb_prop_replay
=
32
;
p
->
sadb_prop_replay
=
32
;
for
(
i
=
1
;
i
<
sizeof
(
aalg_list
)
/
sizeof
(
aalg_list
[
0
]);
i
++
)
{
for
(
i
=
0
;
;
i
++
)
{
if
(
t
->
aalgos
&
(
1
<<
aalg_list
[
i
].
desc
.
sadb_alg_id
))
{
struct
xfrm_algo_desc
*
aalg
=
xfrm_aalg_get_byidx
(
i
);
if
(
!
aalg
)
break
;
if
(
aalg_tmpl_set
(
t
,
aalg
)
&&
aalg
->
available
)
{
struct
sadb_comb
*
c
;
struct
sadb_comb
*
c
;
c
=
(
struct
sadb_comb
*
)
skb_put
(
skb
,
sizeof
(
struct
sadb_comb
));
c
=
(
struct
sadb_comb
*
)
skb_put
(
skb
,
sizeof
(
struct
sadb_comb
));
memset
(
c
,
0
,
sizeof
(
*
c
));
memset
(
c
,
0
,
sizeof
(
*
c
));
p
->
sadb_prop_len
+=
sizeof
(
struct
sadb_comb
)
/
8
;
p
->
sadb_prop_len
+=
sizeof
(
struct
sadb_comb
)
/
8
;
c
->
sadb_comb_auth
=
aalg
_list
[
i
].
desc
.
sadb_alg_id
;
c
->
sadb_comb_auth
=
aalg
->
desc
.
sadb_alg_id
;
c
->
sadb_comb_auth_minbits
=
aalg
_list
[
i
].
desc
.
sadb_alg_minbits
;
c
->
sadb_comb_auth_minbits
=
aalg
->
desc
.
sadb_alg_minbits
;
c
->
sadb_comb_auth_maxbits
=
aalg
_list
[
i
].
desc
.
sadb_alg_maxbits
;
c
->
sadb_comb_auth_maxbits
=
aalg
->
desc
.
sadb_alg_maxbits
;
c
->
sadb_comb_hard_addtime
=
24
*
60
*
60
;
c
->
sadb_comb_hard_addtime
=
24
*
60
*
60
;
c
->
sadb_comb_soft_addtime
=
20
*
60
*
60
;
c
->
sadb_comb_soft_addtime
=
20
*
60
*
60
;
c
->
sadb_comb_hard_usetime
=
8
*
60
*
60
;
c
->
sadb_comb_hard_usetime
=
8
*
60
*
60
;
...
@@ -2010,7 +1940,7 @@ void dump_ah_combs(struct sk_buff *skb, struct xfrm_tmpl *t)
...
@@ -2010,7 +1940,7 @@ void dump_ah_combs(struct sk_buff *skb, struct xfrm_tmpl *t)
}
}
}
}
void
dump_esp_combs
(
struct
sk_buff
*
skb
,
struct
xfrm_tmpl
*
t
)
static
void
dump_esp_combs
(
struct
sk_buff
*
skb
,
struct
xfrm_tmpl
*
t
)
{
{
struct
sadb_prop
*
p
;
struct
sadb_prop
*
p
;
int
i
,
k
;
int
i
,
k
;
...
@@ -2020,22 +1950,30 @@ void dump_esp_combs(struct sk_buff *skb, struct xfrm_tmpl *t)
...
@@ -2020,22 +1950,30 @@ void dump_esp_combs(struct sk_buff *skb, struct xfrm_tmpl *t)
p
->
sadb_prop_exttype
=
SADB_EXT_PROPOSAL
;
p
->
sadb_prop_exttype
=
SADB_EXT_PROPOSAL
;
p
->
sadb_prop_replay
=
32
;
p
->
sadb_prop_replay
=
32
;
for
(
i
=
1
;
i
<
sizeof
(
ealg_list
)
/
sizeof
(
ealg_list
[
0
]);
i
++
)
{
for
(
i
=
0
;
;
i
++
)
{
if
(
!
(
t
->
ealgos
&
(
1
<<
ealg_list
[
i
].
desc
.
sadb_alg_id
)))
struct
xfrm_algo_desc
*
ealg
=
xfrm_ealg_get_byidx
(
i
);
if
(
!
ealg
)
break
;
if
(
!
(
ealg_tmpl_set
(
t
,
ealg
)
&&
ealg
->
available
))
continue
;
continue
;
for
(
k
=
1
;
k
<
sizeof
(
aalg_list
)
/
sizeof
(
aalg_list
[
0
]);
k
++
)
{
for
(
k
=
1
;
;
k
++
)
{
struct
sadb_comb
*
c
;
struct
sadb_comb
*
c
;
if
(
!
(
t
->
aalgos
&
(
1
<<
aalg_list
[
i
].
desc
.
sadb_alg_id
)))
struct
xfrm_algo_desc
*
aalg
=
xfrm_aalg_get_byidx
(
k
);
if
(
!
aalg
)
break
;
if
(
!
(
aalg_tmpl_set
(
t
,
aalg
)
&&
aalg
->
available
))
continue
;
continue
;
c
=
(
struct
sadb_comb
*
)
skb_put
(
skb
,
sizeof
(
struct
sadb_comb
));
c
=
(
struct
sadb_comb
*
)
skb_put
(
skb
,
sizeof
(
struct
sadb_comb
));
memset
(
c
,
0
,
sizeof
(
*
c
));
memset
(
c
,
0
,
sizeof
(
*
c
));
p
->
sadb_prop_len
+=
sizeof
(
struct
sadb_comb
)
/
8
;
p
->
sadb_prop_len
+=
sizeof
(
struct
sadb_comb
)
/
8
;
c
->
sadb_comb_auth
=
aalg
_list
[
k
].
desc
.
sadb_alg_id
;
c
->
sadb_comb_auth
=
aalg
->
desc
.
sadb_alg_id
;
c
->
sadb_comb_auth_minbits
=
aalg
_list
[
k
].
desc
.
sadb_alg_minbits
;
c
->
sadb_comb_auth_minbits
=
aalg
->
desc
.
sadb_alg_minbits
;
c
->
sadb_comb_auth_maxbits
=
aalg
_list
[
k
].
desc
.
sadb_alg_maxbits
;
c
->
sadb_comb_auth_maxbits
=
aalg
->
desc
.
sadb_alg_maxbits
;
c
->
sadb_comb_encrypt
=
ealg
_list
[
i
].
desc
.
sadb_alg_id
;
c
->
sadb_comb_encrypt
=
ealg
->
desc
.
sadb_alg_id
;
c
->
sadb_comb_encrypt_minbits
=
ealg
_list
[
i
].
desc
.
sadb_alg_minbits
;
c
->
sadb_comb_encrypt_minbits
=
ealg
->
desc
.
sadb_alg_minbits
;
c
->
sadb_comb_encrypt_maxbits
=
ealg
_list
[
i
].
desc
.
sadb_alg_maxbits
;
c
->
sadb_comb_encrypt_maxbits
=
ealg
->
desc
.
sadb_alg_maxbits
;
c
->
sadb_comb_hard_addtime
=
24
*
60
*
60
;
c
->
sadb_comb_hard_addtime
=
24
*
60
*
60
;
c
->
sadb_comb_soft_addtime
=
20
*
60
*
60
;
c
->
sadb_comb_soft_addtime
=
20
*
60
*
60
;
c
->
sadb_comb_hard_usetime
=
8
*
60
*
60
;
c
->
sadb_comb_hard_usetime
=
8
*
60
*
60
;
...
...
net/netsyms.c
View file @
3bab27b6
...
@@ -323,6 +323,15 @@ EXPORT_SYMBOL(xfrm_policy_flush);
...
@@ -323,6 +323,15 @@ EXPORT_SYMBOL(xfrm_policy_flush);
EXPORT_SYMBOL
(
xfrm_policy_byid
);
EXPORT_SYMBOL
(
xfrm_policy_byid
);
EXPORT_SYMBOL
(
xfrm_policy_list
);
EXPORT_SYMBOL
(
xfrm_policy_list
);
EXPORT_SYMBOL_GPL
(
xfrm_probe_algs
);
EXPORT_SYMBOL_GPL
(
xfrm_count_auth_supported
);
EXPORT_SYMBOL_GPL
(
xfrm_count_enc_supported
);
EXPORT_SYMBOL_GPL
(
xfrm_aalg_get_byidx
);
EXPORT_SYMBOL_GPL
(
xfrm_ealg_get_byidx
);
EXPORT_SYMBOL_GPL
(
xfrm_aalg_get_byid
);
EXPORT_SYMBOL_GPL
(
xfrm_ealg_get_byid
);
EXPORT_SYMBOL_GPL
(
xfrm_aalg_get_byname
);
EXPORT_SYMBOL_GPL
(
xfrm_ealg_get_byname
);
#if defined (CONFIG_IPV6_MODULE) || defined (CONFIG_IP_SCTP_MODULE)
#if defined (CONFIG_IPV6_MODULE) || defined (CONFIG_IP_SCTP_MODULE)
/* inet functions common to v4 and v6 */
/* inet functions common to v4 and v6 */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment