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
nexedi
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
Hide 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
...
@@ -242,17 +242,25 @@ struct sadb_x_ipsecrequest {
...
@@ -242,17 +242,25 @@ struct sadb_x_ipsecrequest {
#define SADB_SATYPE_MAX 9
#define SADB_SATYPE_MAX 9
/* Authentication algorithms */
/* Authentication algorithms */
#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_EALG_NULL 11
#define SADB_X_EALG_CASTCBC 6
#define SADB_EALG_MAX 11
#define SADB_X_EALG_BLOWFISHCBC 7
#define SADB_EALG_NULL 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
;
}
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
;
goto
error
;
x
->
props
.
header_len
=
(
12
+
ahp
->
digest_len
+
7
)
&~
7
;
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
=
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
++
)
{
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