Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
dffa3949
Commit
dffa3949
authored
Sep 05, 2016
by
Christian Heimes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #27744: Add AF_ALG (Linux Kernel crypto) to socket module.
parent
92a6c170
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
646 additions
and
72 deletions
+646
-72
Doc/library/socket.rst
Doc/library/socket.rst
+49
-6
Lib/test/test_socket.py
Lib/test/test_socket.py
+165
-0
Misc/NEWS
Misc/NEWS
+2
-0
Modules/socketmodule.c
Modules/socketmodule.c
+378
-53
configure
configure
+36
-13
configure.ac
configure.ac
+13
-0
pyconfig.h.in
pyconfig.h.in
+3
-0
No files found.
Doc/library/socket.rst
View file @
dffa3949
...
...
@@ -131,6 +131,22 @@ created. Socket addresses are represented as follows:
string format. (ex. ``b'12:23:34:45:56:67'``) This protocol is not
supported under FreeBSD.
- :const:`AF_ALG` is a Linux-only socket based interface to Kernel
cryptography. An algorithm socket is configured with a tuple of two to four
elements ``(type, name [, feat [, mask]])``, where:
- *type* is the algorithm type as string, e.g. ``aead``, ``hash``,
``skcipher`` or ``rng``.
- *name* is the algorithm name and operation mode as string, e.g.
``sha256``, ``hmac(sha256)``, ``cbc(aes)`` or ``drbg_nopr_ctr_aes256``.
- *feat* and *mask* are unsigned 32bit integers.
Availability Linux 2.6.38, some algorithm types require more recent Kernels.
.. versionadded:: 3.6
- Certain other address families (:const:`AF_PACKET`, :const:`AF_CAN`)
support specific representations.
...
...
@@ -350,6 +366,16 @@ Constants
TIPC related constants, matching the ones exported by the C socket API. See
the TIPC documentation for more information.
.. data:: AF_ALG
SOL_ALG
ALG_*
Constants for Linux Kernel cryptography.
Availability: Linux >= 2.6.38.
.. versionadded:: 3.6
.. data:: AF_LINK
Availability: BSD, OSX.
...
...
@@ -1294,6 +1320,15 @@ to sockets.
an exception, the method now retries the system call instead of raising
an :exc:`InterruptedError` exception (see :pep:`475` for the rationale).
.. method:: socket.sendmsg_afalg([msg], *, op[, iv[, assoclen[, flags]]])
Specialized version of :meth:`~socket.sendmsg` for :const:`AF_ALG` socket.
Set mode, IV, AEAD associated data length and flags for :const:`AF_ALG` socket.
Availability: Linux >= 2.6.38
.. versionadded:: 3.6
.. method:: socket.sendfile(file, offset=0, count=None)
Send a file until EOF is reached by using high-performance
...
...
@@ -1342,21 +1377,29 @@ to sockets.
For further information, please consult the :ref:`notes on socket timeouts <socket-timeouts>`.
.. method:: socket.setsockopt(level, optname, value)
.. method:: socket.setsockopt(level, optname, value: int)
.. method:: socket.setsockopt(level, optname, value: buffer)
.. method:: socket.setsockopt(level, optname, None, optlen: int)
.. index:: module: struct
Set the value of the given socket option (see the Unix manual page
:manpage:`setsockopt(2)`). The needed symbolic constants are defined in the
:mod:`socket` module (:const:`SO_\*` etc.). The value can be an integer or
a :term:`bytes-like object` representing a buffer. In the latter case it is
up to the caller to
ensure that the bytestring contains the proper bits (see the optional built-in
module :mod:`struct` for a way to encode C structures as bytestrings).
:mod:`socket` module (:const:`SO_\*` etc.). The value can be an integer,
None or a :term:`bytes-like object` representing a buffer. In the later
case it is up to the caller to ensure that the bytestring contains the
proper bits (see the optional built-in module :mod:`struct` for a way to
encode C structures as bytestrings). When value is set to None,
optlen argument is required. It's equivalent to call setsockopt C
function with optval=NULL and optlen=optlen.
.. versionchanged:: 3.5
Writable :term:`bytes-like object` is now accepted.
.. versionchanged:: 3.6
setsockopt(level, optname, None, optlen: int) form added.
.. method:: socket.shutdown(how)
...
...
Lib/test/test_socket.py
View file @
dffa3949
...
...
@@ -5325,6 +5325,170 @@ class SendfileUsingSendfileTest(SendfileUsingSendTest):
def
meth_from_sock
(
self
,
sock
):
return
getattr
(
sock
,
"_sendfile_use_sendfile"
)
@
unittest
.
skipUnless
(
hasattr
(
socket
,
"AF_ALG"
),
'AF_ALG required'
)
class
LinuxKernelCryptoAPI
(
unittest
.
TestCase
):
# tests for AF_ALG
def
create_alg
(
self
,
typ
,
name
):
sock
=
socket
.
socket
(
socket
.
AF_ALG
,
socket
.
SOCK_SEQPACKET
,
0
)
sock
.
bind
((
typ
,
name
))
return
sock
def
test_sha256
(
self
):
expected
=
bytes
.
fromhex
(
"ba7816bf8f01cfea414140de5dae2223b00361a396"
"177a9cb410ff61f20015ad"
)
with
self
.
create_alg
(
'hash'
,
'sha256'
)
as
algo
:
op
,
_
=
algo
.
accept
()
with
op
:
op
.
sendall
(
b"abc"
)
self
.
assertEqual
(
op
.
recv
(
512
),
expected
)
op
,
_
=
algo
.
accept
()
with
op
:
op
.
send
(
b'a'
,
socket
.
MSG_MORE
)
op
.
send
(
b'b'
,
socket
.
MSG_MORE
)
op
.
send
(
b'c'
,
socket
.
MSG_MORE
)
op
.
send
(
b''
)
self
.
assertEqual
(
op
.
recv
(
512
),
expected
)
def
test_hmac_sha1
(
self
):
expected
=
bytes
.
fromhex
(
"effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"
)
with
self
.
create_alg
(
'hash'
,
'hmac(sha1)'
)
as
algo
:
algo
.
setsockopt
(
socket
.
SOL_ALG
,
socket
.
ALG_SET_KEY
,
b"Jefe"
)
op
,
_
=
algo
.
accept
()
with
op
:
op
.
sendall
(
b"what do ya want for nothing?"
)
self
.
assertEqual
(
op
.
recv
(
512
),
expected
)
def
test_aes_cbc
(
self
):
key
=
bytes
.
fromhex
(
'06a9214036b8a15b512e03d534120006'
)
iv
=
bytes
.
fromhex
(
'3dafba429d9eb430b422da802c9fac41'
)
msg
=
b"Single block msg"
ciphertext
=
bytes
.
fromhex
(
'e353779c1079aeb82708942dbe77181a'
)
msglen
=
len
(
msg
)
with
self
.
create_alg
(
'skcipher'
,
'cbc(aes)'
)
as
algo
:
algo
.
setsockopt
(
socket
.
SOL_ALG
,
socket
.
ALG_SET_KEY
,
key
)
op
,
_
=
algo
.
accept
()
with
op
:
op
.
sendmsg_afalg
(
op
=
socket
.
ALG_OP_ENCRYPT
,
iv
=
iv
,
flags
=
socket
.
MSG_MORE
)
op
.
sendall
(
msg
)
self
.
assertEqual
(
op
.
recv
(
msglen
),
ciphertext
)
op
,
_
=
algo
.
accept
()
with
op
:
op
.
sendmsg_afalg
([
ciphertext
],
op
=
socket
.
ALG_OP_DECRYPT
,
iv
=
iv
)
self
.
assertEqual
(
op
.
recv
(
msglen
),
msg
)
# long message
multiplier
=
1024
longmsg
=
[
msg
]
*
multiplier
op
,
_
=
algo
.
accept
()
with
op
:
op
.
sendmsg_afalg
(
longmsg
,
op
=
socket
.
ALG_OP_ENCRYPT
,
iv
=
iv
)
enc
=
op
.
recv
(
msglen
*
multiplier
)
self
.
assertEqual
(
len
(
enc
),
msglen
*
multiplier
)
self
.
assertTrue
(
enc
[:
msglen
],
ciphertext
)
op
,
_
=
algo
.
accept
()
with
op
:
op
.
sendmsg_afalg
([
enc
],
op
=
socket
.
ALG_OP_DECRYPT
,
iv
=
iv
)
dec
=
op
.
recv
(
msglen
*
multiplier
)
self
.
assertEqual
(
len
(
dec
),
msglen
*
multiplier
)
self
.
assertEqual
(
dec
,
msg
*
multiplier
)
@
support
.
requires_linux_version
(
3
,
19
)
def
test_aead_aes_gcm
(
self
):
key
=
bytes
.
fromhex
(
'c939cc13397c1d37de6ae0e1cb7c423c'
)
iv
=
bytes
.
fromhex
(
'b3d8cc017cbb89b39e0f67e2'
)
plain
=
bytes
.
fromhex
(
'c3b3c41f113a31b73d9a5cd432103069'
)
assoc
=
bytes
.
fromhex
(
'24825602bd12a984e0092d3e448eda5f'
)
expected_ct
=
bytes
.
fromhex
(
'93fe7d9e9bfd10348a5606e5cafa7354'
)
expected_tag
=
bytes
.
fromhex
(
'0032a1dc85f1c9786925a2e71d8272dd'
)
taglen
=
len
(
expected_tag
)
assoclen
=
len
(
assoc
)
with
self
.
create_alg
(
'aead'
,
'gcm(aes)'
)
as
algo
:
algo
.
setsockopt
(
socket
.
SOL_ALG
,
socket
.
ALG_SET_KEY
,
key
)
algo
.
setsockopt
(
socket
.
SOL_ALG
,
socket
.
ALG_SET_AEAD_AUTHSIZE
,
None
,
taglen
)
# send assoc, plain and tag buffer in separate steps
op
,
_
=
algo
.
accept
()
with
op
:
op
.
sendmsg_afalg
(
op
=
socket
.
ALG_OP_ENCRYPT
,
iv
=
iv
,
assoclen
=
assoclen
,
flags
=
socket
.
MSG_MORE
)
op
.
sendall
(
assoc
,
socket
.
MSG_MORE
)
op
.
sendall
(
plain
,
socket
.
MSG_MORE
)
op
.
sendall
(
b'
\
x00
'
*
taglen
)
res
=
op
.
recv
(
assoclen
+
len
(
plain
)
+
taglen
)
self
.
assertEqual
(
expected_ct
,
res
[
assoclen
:
-
taglen
])
self
.
assertEqual
(
expected_tag
,
res
[
-
taglen
:])
# now with msg
op
,
_
=
algo
.
accept
()
with
op
:
msg
=
assoc
+
plain
+
b'
\
x00
'
*
taglen
op
.
sendmsg_afalg
([
msg
],
op
=
socket
.
ALG_OP_ENCRYPT
,
iv
=
iv
,
assoclen
=
assoclen
)
res
=
op
.
recv
(
assoclen
+
len
(
plain
)
+
taglen
)
self
.
assertEqual
(
expected_ct
,
res
[
assoclen
:
-
taglen
])
self
.
assertEqual
(
expected_tag
,
res
[
-
taglen
:])
# create anc data manually
pack_uint32
=
struct
.
Struct
(
'I'
).
pack
op
,
_
=
algo
.
accept
()
with
op
:
msg
=
assoc
+
plain
+
b'
\
x00
'
*
taglen
op
.
sendmsg
(
[
msg
],
([
socket
.
SOL_ALG
,
socket
.
ALG_SET_OP
,
pack_uint32
(
socket
.
ALG_OP_ENCRYPT
)],
[
socket
.
SOL_ALG
,
socket
.
ALG_SET_IV
,
pack_uint32
(
len
(
iv
))
+
iv
],
[
socket
.
SOL_ALG
,
socket
.
ALG_SET_AEAD_ASSOCLEN
,
pack_uint32
(
assoclen
)],
)
)
res
=
op
.
recv
(
len
(
msg
))
self
.
assertEqual
(
expected_ct
,
res
[
assoclen
:
-
taglen
])
self
.
assertEqual
(
expected_tag
,
res
[
-
taglen
:])
# decrypt and verify
op
,
_
=
algo
.
accept
()
with
op
:
msg
=
assoc
+
expected_ct
+
expected_tag
op
.
sendmsg_afalg
([
msg
],
op
=
socket
.
ALG_OP_DECRYPT
,
iv
=
iv
,
assoclen
=
assoclen
)
res
=
op
.
recv
(
len
(
msg
))
self
.
assertEqual
(
plain
,
res
[
assoclen
:
-
taglen
])
def
test_drbg_pr_sha256
(
self
):
# deterministic random bit generator, prediction resistance, sha256
with
self
.
create_alg
(
'rng'
,
'drbg_pr_sha256'
)
as
algo
:
extra_seed
=
os
.
urandom
(
32
)
algo
.
setsockopt
(
socket
.
SOL_ALG
,
socket
.
ALG_SET_KEY
,
extra_seed
)
op
,
_
=
algo
.
accept
()
with
op
:
rn
=
op
.
recv
(
32
)
self
.
assertEqual
(
len
(
rn
),
32
)
def
test_sendmsg_afalg_args
(
self
):
sock
=
socket
.
socket
(
socket
.
AF_ALG
,
socket
.
SOCK_SEQPACKET
,
0
)
with
self
.
assertRaises
(
TypeError
):
sock
.
sendmsg_afalg
()
with
self
.
assertRaises
(
TypeError
):
sock
.
sendmsg_afalg
(
op
=
None
)
with
self
.
assertRaises
(
TypeError
):
sock
.
sendmsg_afalg
(
1
)
with
self
.
assertRaises
(
TypeError
):
sock
.
sendmsg_afalg
(
op
=
socket
.
ALG_OP_ENCRYPT
,
assoclen
=
None
)
with
self
.
assertRaises
(
TypeError
):
sock
.
sendmsg_afalg
(
op
=
socket
.
ALG_OP_ENCRYPT
,
assoclen
=-
1
)
def
test_main
():
tests
=
[
GeneralModuleTests
,
BasicTCPTest
,
TCPCloserTest
,
TCPTimeoutTest
,
...
...
@@ -5352,6 +5516,7 @@ def test_main():
tests
.
extend
([
TIPCTest
,
TIPCThreadableTest
])
tests
.
extend
([
BasicCANTest
,
CANTest
])
tests
.
extend
([
BasicRDSTest
,
RDSTest
])
tests
.
append
(
LinuxKernelCryptoAPI
)
tests
.
extend
([
CmsgMacroTests
,
SendmsgUDPTest
,
...
...
Misc/NEWS
View file @
dffa3949
...
...
@@ -77,6 +77,8 @@ Core and Builtins
Library
-------
- Issue #27744: Add AF_ALG (Linux Kernel crypto) to socket module.
- Issue #26470: Port ssl and hashlib module to OpenSSL 1.1.0.
- Issue #11620: Fix support for SND_MEMORY in winsound.PlaySound. Based on a
...
...
Modules/socketmodule.c
View file @
dffa3949
This diff is collapsed.
Click to expand it.
configure
View file @
dffa3949
...
...
@@ -775,7 +775,6 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
...
...
@@ -886,7 +885,6 @@ datadir='${datarootdir}'
sysconfdir
=
'${prefix}/etc'
sharedstatedir
=
'${prefix}/com'
localstatedir
=
'${prefix}/var'
runstatedir
=
'${localstatedir}/run'
includedir
=
'${prefix}/include'
oldincludedir
=
'/usr/include'
docdir
=
'${datarootdir}/doc/${PACKAGE_TARNAME}'
...
...
@@ -1139,15 +1137,6 @@ do
|
-silent
|
--silent
|
--silen
|
--sile
|
--sil
)
silent
=
yes
;;
-runstatedir
|
--runstatedir
|
--runstatedi
|
--runstated
\
|
--runstate
|
--runstat
|
--runsta
|
--runst
|
--runs
\
|
--run
|
--ru
|
--r
)
ac_prev
=
runstatedir
;;
-runstatedir
=
*
|
--runstatedir
=
*
|
--runstatedi
=
*
|
--runstated
=
*
\
|
--runstate
=
*
|
--runstat
=
*
|
--runsta
=
*
|
--runst
=
*
|
--runs
=
*
\
|
--run
=
*
|
--ru
=
*
|
--r
=
*
)
runstatedir
=
$ac_optarg
;;
-sbindir
|
--sbindir
|
--sbindi
|
--sbind
|
--sbin
|
--sbi
|
--sb
)
ac_prev
=
sbindir
;;
-sbindir
=
*
|
--sbindir
=
*
|
--sbindi
=
*
|
--sbind
=
*
|
--sbin
=
*
\
...
...
@@ -1285,7 +1274,7 @@ fi
for
ac_var
in
exec_prefix prefix bindir sbindir libexecdir datarootdir
\
datadir sysconfdir sharedstatedir localstatedir includedir
\
oldincludedir docdir infodir htmldir dvidir pdfdir psdir
\
libdir localedir mandir
runstatedir
libdir localedir mandir
do
eval
ac_val
=
\$
$ac_var
# Remove trailing slashes.
...
...
@@ -1438,7 +1427,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
...
...
@@ -13062,6 +13050,41 @@ $as_echo "#define HAVE_SOCKADDR_STORAGE 1" >>confdefs.h
fi
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: checking for sockaddr_alg"
>
&5
$as_echo_n
"checking for sockaddr_alg... "
>
&6
;
}
if
${
ac_cv_struct_sockaddr_alg
+
:
}
false
;
then
:
$as_echo_n
"(cached) "
>
&6
else
cat
confdefs.h -
<<
_ACEOF
>conftest.
$ac_ext
/* end confdefs.h. */
# include <sys/types.h>
# include <sys/socket.h>
# include <linux/if_alg.h>
int
main ()
{
struct sockaddr_alg s
;
return 0;
}
_ACEOF
if
ac_fn_c_try_compile
"
$LINENO
"
;
then
:
ac_cv_struct_sockaddr_alg
=
yes
else
ac_cv_struct_sockaddr_alg
=
no
fi
rm
-f
core conftest.err conftest.
$ac_objext
conftest.
$ac_ext
fi
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: result:
$ac_cv_struct_sockaddr_alg
"
>
&5
$as_echo
"
$ac_cv_struct_sockaddr_alg
"
>
&6
;
}
if
test
$ac_cv_struct_sockaddr_alg
=
yes
;
then
$as_echo
"#define HAVE_SOCKADDR_ALG 1"
>>
confdefs.h
fi
# checks for compiler characteristics
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: checking whether char is unsigned"
>
&5
...
...
configure.ac
View file @
dffa3949
...
...
@@ -3862,6 +3862,19 @@ if test $ac_cv_struct_sockaddr_storage = yes; then
AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1, [struct sockaddr_storage (sys/socket.h)])
fi
AC_MSG_CHECKING(for sockaddr_alg)
AC_CACHE_VAL(ac_cv_struct_sockaddr_alg,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
# include <sys/types.h>
# include <sys/socket.h>
# include <linux/if_alg.h>]], [[struct sockaddr_alg s]])],
[ac_cv_struct_sockaddr_alg=yes],
[ac_cv_struct_sockaddr_alg=no]))
AC_MSG_RESULT($ac_cv_struct_sockaddr_alg)
if test $ac_cv_struct_sockaddr_alg = yes; then
AC_DEFINE(HAVE_SOCKADDR_ALG, 1, [struct sockaddr_alg (linux/if_alg.h)])
fi
# checks for compiler characteristics
AC_C_CHAR_UNSIGNED
...
...
pyconfig.h.in
View file @
dffa3949
...
...
@@ -892,6 +892,9 @@
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* struct sockaddr_alg (linux/if_alg.h) */
#undef HAVE_SOCKADDR_ALG
/* Define if sockaddr has sa_len member */
#undef HAVE_SOCKADDR_SA_LEN
...
...
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