Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Wim Lewis
nettle
Commits
aa7ad293
Commit
aa7ad293
authored
Jan 13, 2015
by
Niels Möller
Browse files
Initial support for fat x86_64 build.
parent
23b9cf22
Changes
9
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
aa7ad293
2015-01-13 Niels Möller <nisse@lysator.liu.se>
* x86_64/fat/fat.c: New file, initialization for x86_64 fat
library.
* x86_64/fat/cpuid.asm (_nettle_cpuid): New file and function.
* x86_64/fat/aes-encrypt-internal.asm: New file, including
x86_64/aes-encrypt-internal.asm, after setting fat_suffix to
_x86_64.
* x86_64/fat/aes-decrypt-internal.asm: New file, analogous setup.
* x86_64/fat/aes-encrypt-internal-2.asm: New file, including
x86_64/aesni/aes-encrypt-internal.asm, after setting fat_suffix to
_aesni.
* x86_64/fat/aes-decrypt-internal.asm-2: New file, analogous
setup.
* configure.ac: New command line option --enable-fat.
(asm_nettle_optional_list): Added cpuid.asm, fat.c,
aes-encrypt-internal-2.asm, and aes-decrypt-internal-2.asm.
* asm.m4 (fat_suffix): New suffix added to symbol names.
* x86_64/aesni/aes-encrypt-internal.asm: Use explicit .byte
sequences for aes instructions, don't rely on assembler support.
* x86_64/aesni/aes-decrypt-internal.asm: Likewise.
...
...
asm.m4
View file @
aa7ad293
...
...
@@ -12,6 +12,9 @@ changecom()dnl
dnl Including files from the srcdir
define(<include_src>, <include(srcdir/$1)>)dnl
dnl default definition, changed in fat builds
define(<fat_suffix>, <>)
dnl Pseudo ops
define(<DECLARE_FUNC>,
<ifelse(ELF_STYLE,yes,
...
...
@@ -24,13 +27,13 @@ COFF_STYLE, yes,
<>)>)
define(<PROLOGUE>,
<.globl C_NAME($1)
DECLARE_FUNC(C_NAME($1))
C_NAME($1):>)
<.globl C_NAME($1)
<>fat_suffix
DECLARE_FUNC(C_NAME($1)
<>fat_suffix
)
C_NAME($1)
<>fat_suffix
:>)
define(<EPILOGUE>,
<ifelse(ELF_STYLE,yes,
<.size C_NAME($1), . - C_NAME($1)>,<>)>)
<.size C_NAME($1)
<>fat_suffix
, . - C_NAME($1)
<>fat_suffix
>,<>)>)
define(<m4_log2>, <m4_log2_internal($1,1,0)>)
define(<m4_log2_internal>,
...
...
configure.ac
View file @
aa7ad293
...
...
@@ -68,6 +68,9 @@ AC_ARG_ENABLE(documentation,
AC_HELP_STRING([--disable-documentation], [Omit building and installing the documentation. (default=auto)]),,
[enable_documentation=auto])
AC_ARG_ENABLE(fat, AC_HELP_STRING([--enable-fat], [Enable fat library build (default=no)]),,
[enable_fat=no])
AC_ARG_ENABLE(arm-neon,
AC_HELP_STRING([--enable-arm-neon], [Enable ARM Neon assembly. (default=auto)]),,
[enable_arm_neon=auto])
...
...
@@ -248,6 +251,9 @@ if test "x$enable_assembler" = xyes ; then
if test "x$enable_x86_aesni" = xyes ; then
asm_path="x86_64/aesni $asm_path"
fi
if test "x$enable_fat" = xyes ; then
asm_path="x86_64/fat $asm_path"
fi
else
asm_path=x86
fi
...
...
@@ -290,7 +296,8 @@ asm_replace_list="aes-encrypt-internal.asm aes-decrypt-internal.asm \
sha3-permute.asm umac-nh.asm umac-nh-n.asm machine.m4"
# Assembler files which generate additional object files if they are used.
asm_nettle_optional_list="gcm-hash8.asm"
asm_nettle_optional_list="gcm-hash8.asm cpuid.asm fat.c \
aes-encrypt-internal-2.asm aes-decrypt-internal-2.asm"
asm_hogweed_optional_list=""
if test "x$enable_public_key" = "xyes" ; then
asm_hogweed_optional_list="ecc-192-modp.asm ecc-224-modp.asm \
...
...
x86_64/fat/aes-decrypt-internal-2.asm
0 → 100644
View file @
aa7ad293
C
x86_64
/
fat
/
aes
-
decrypt
-
internal
-
2
.asm
ifelse
(
<
Copyright
(
C
)
2015
Niels
M
ö
ller
This
file
is
part
of
GNU
Nettle.
GNU
Nettle
is
free
software
:
you
can
redistribute
it
and
/
or
modify
it
under
the
terms
of
either
:
*
the
GNU
Lesser
General
Public
License
as
published
by
the
Free
Software
Foundation
; either version 3 of the License, or (at your
option
)
any
later
version.
or
*
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.
or
both
in
parallel
,
as
here.
GNU
Nettle
is
di
stributed
in
the
hope
that
it
will
be
useful
,
but
WITHOUT
ANY
WARRANTY
; without even the implied warranty of
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE.
See
the
GNU
General
Public
License
for
more
details.
You
should
have
received
copies
of
the
GNU
General
Public
License
and
the
GNU
Lesser
General
Public
License
al
ong
with
this
program.
If
not
,
see
http
:
//
www.gnu.org
/
licenses
/
.
>)
define
(
<
fat_suffix
>
,
<
_aesni
>
)
include_src
(
<
x86_64
/
aesni
/
aes
-
decrypt
-
internal.asm
>
)
x86_64/fat/aes-decrypt-internal.asm
0 → 100644
View file @
aa7ad293
C
x86_64
/
fat
/
aes
-
decrypt
-
internal.asm
ifelse
(
<
Copyright
(
C
)
2015
Niels
M
ö
ller
This
file
is
part
of
GNU
Nettle.
GNU
Nettle
is
free
software
:
you
can
redistribute
it
and
/
or
modify
it
under
the
terms
of
either
:
*
the
GNU
Lesser
General
Public
License
as
published
by
the
Free
Software
Foundation
; either version 3 of the License, or (at your
option
)
any
later
version.
or
*
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.
or
both
in
parallel
,
as
here.
GNU
Nettle
is
di
stributed
in
the
hope
that
it
will
be
useful
,
but
WITHOUT
ANY
WARRANTY
; without even the implied warranty of
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE.
See
the
GNU
General
Public
License
for
more
details.
You
should
have
received
copies
of
the
GNU
General
Public
License
and
the
GNU
Lesser
General
Public
License
al
ong
with
this
program.
If
not
,
see
http
:
//
www.gnu.org
/
licenses
/
.
>)
define
(
<
fat_suffix
>
,
<
_x86_64
>
)
include_src
(
<
x86_64
/
aes
-
decrypt
-
internal.asm
>
)
x86_64/fat/aes-encrypt-internal-2.asm
0 → 100644
View file @
aa7ad293
C
x86_64
/
fat
/
aes
-
encrypt
-
internal
-
2
.asm
ifelse
(
<
Copyright
(
C
)
2015
Niels
M
ö
ller
This
file
is
part
of
GNU
Nettle.
GNU
Nettle
is
free
software
:
you
can
redistribute
it
and
/
or
modify
it
under
the
terms
of
either
:
*
the
GNU
Lesser
General
Public
License
as
published
by
the
Free
Software
Foundation
; either version 3 of the License, or (at your
option
)
any
later
version.
or
*
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.
or
both
in
parallel
,
as
here.
GNU
Nettle
is
di
stributed
in
the
hope
that
it
will
be
useful
,
but
WITHOUT
ANY
WARRANTY
; without even the implied warranty of
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE.
See
the
GNU
General
Public
License
for
more
details.
You
should
have
received
copies
of
the
GNU
General
Public
License
and
the
GNU
Lesser
General
Public
License
al
ong
with
this
program.
If
not
,
see
http
:
//
www.gnu.org
/
licenses
/
.
>)
define
(
<
fat_suffix
>
,
<
_aesni
>
)
include_src
(
<
x86_64
/
aesni
/
aes
-
encrypt
-
internal.asm
>
)
x86_64/fat/aes-encrypt-internal.asm
0 → 100644
View file @
aa7ad293
C
x86_64
/
fat
/
aes
-
encrypt
-
internal.asm
ifelse
(
<
Copyright
(
C
)
2015
Niels
M
ö
ller
This
file
is
part
of
GNU
Nettle.
GNU
Nettle
is
free
software
:
you
can
redistribute
it
and
/
or
modify
it
under
the
terms
of
either
:
*
the
GNU
Lesser
General
Public
License
as
published
by
the
Free
Software
Foundation
; either version 3 of the License, or (at your
option
)
any
later
version.
or
*
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.
or
both
in
parallel
,
as
here.
GNU
Nettle
is
di
stributed
in
the
hope
that
it
will
be
useful
,
but
WITHOUT
ANY
WARRANTY
; without even the implied warranty of
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE.
See
the
GNU
General
Public
License
for
more
details.
You
should
have
received
copies
of
the
GNU
General
Public
License
and
the
GNU
Lesser
General
Public
License
al
ong
with
this
program.
If
not
,
see
http
:
//
www.gnu.org
/
licenses
/
.
>)
define
(
<
fat_suffix
>
,
<
_x86_64
>
)
include_src
(
<
x86_64
/
aes
-
encrypt
-
internal.asm
>
)
x86_64/fat/cpuid.asm
0 → 100644
View file @
aa7ad293
C
x86_64
/
fat
/
cpuid.asm
ifelse
(
<
Copyright
(
C
)
2015
Niels
M
ö
ller
This
file
is
part
of
GNU
Nettle.
GNU
Nettle
is
free
software
:
you
can
redistribute
it
and
/
or
modify
it
under
the
terms
of
either
:
*
the
GNU
Lesser
General
Public
License
as
published
by
the
Free
Software
Foundation
; either version 3 of the License, or (at your
option
)
any
later
version.
or
*
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.
or
both
in
parallel
,
as
here.
GNU
Nettle
is
di
stributed
in
the
hope
that
it
will
be
useful
,
but
WITHOUT
ANY
WARRANTY
; without even the implied warranty of
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE.
See
the
GNU
General
Public
License
for
more
details.
You
should
have
received
copies
of
the
GNU
General
Public
License
and
the
GNU
Lesser
General
Public
License
al
ong
with
this
program.
If
not
,
see
http
:
//
www.gnu.org
/
licenses
/
.
>)
C
Input
argument
C
cpuid
input
:
%
edi
C
output
pointer
:
%
rsi
.file
"cpuid.asm"
C
void
_nettle_cpuid
(
uint32_t
in
,
uint32_t
*
out
)
.text
ALIGN
(
16
)
PROLOGUE
(
_nettle_cpuid
)
W64_ENTRY
(
2
)
push
%
rbx
movl
%
edi
,
%
eax
cpuid
mov
%
eax
,
(
%
rsi
)
mov
%
ebx
,
4
(
%
rsi
)
mov
%
ecx
,
8
(
%
rsi
)
mov
%
edx
,
12
(
%
rsi
)
pop
%
rbx
W64_EXIT
(
2
)
ret
EPILOGUE
(
_nettle_cpuid
)
x86_64/fat/fat.c
0 → 100644
View file @
aa7ad293
/* fat.c
Copyright (C) 2015 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* 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.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include
<assert.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
"nettle-types.h"
#include
"aes-internal.h"
/* Fat library initialization works as follows. The main function is
fat_init. It tries to do initialization only once, but since it is
idempotent and pointer updates are atomic on x86_64, there's no
harm if it is in some cases called multiple times from several
threads.
The fat_init function checks the cpuid flags, and sets function
pointers, e.g, _aes_encrypt_vec, to point to the appropriate
implementation.
To get everything hooked in, we use a belt-and-suspenders approach.
When compiling with gcc, we try to register a constructor function
which calls fat_init as soon as the library is loaded. If this is
unavailable or non-working, we instead arrange fat_init to be
called on demand.
For the actual indirection, there are two cases.
If ifunc support is available, function pointers are statically
initialized to NULL, and we register resolver functions, e.g.,
_aes_encrypt_resolve, which calls fat_init, and then returns the
function pointer, e.g., the value of _aes_encrypt_vec.
If ifunc is not available, we have to define a wrapper function to
jump via the function pointer. (FIXME: For internal calls, we could
do this as a macro instead). We statically initialize each function
pointer to point to a special initialization function, e.g.,
_aes_encrypt_init, which calls fat_init, and then invokes the right
function. This way, all pointers are setup correctly at the first
call to any fat function.
*/
#if HAVE_LINK_IFUNC
# define IFUNC(resolve) __attribute__ ((ifunc (resolve)))
#else
# define IFUNC(resolve)
#endif
void
_nettle_cpuid
(
uint32_t
input
,
uint32_t
regs
[
4
]);
typedef
void
void_func
(
void
);
typedef
void
aes_crypt_internal_func
(
unsigned
rounds
,
const
uint32_t
*
keys
,
const
struct
aes_table
*
T
,
size_t
length
,
uint8_t
*
dst
,
const
uint8_t
*
src
);
aes_crypt_internal_func
_aes_encrypt
IFUNC
(
"_aes_encrypt_resolve"
);
aes_crypt_internal_func
_nettle_aes_encrypt_x86_64
;
aes_crypt_internal_func
_nettle_aes_encrypt_aesni
;
aes_crypt_internal_func
_aes_decrypt
IFUNC
(
"_aes_decrypt_resolve"
);
aes_crypt_internal_func
_nettle_aes_decrypt_x86_64
;
aes_crypt_internal_func
_nettle_aes_decrypt_aesni
;
#if HAVE_LINK_IFUNC
#define _aes_encrypt_init NULL
#define _aes_decrypt_init NULL
#else
static
aes_crypt_internal_func
_aes_encrypt_init
;
static
aes_crypt_internal_func
_aes_decrypt_init
;
#endif
static
aes_crypt_internal_func
*
_aes_encrypt_vec
=
_aes_encrypt_init
;
static
aes_crypt_internal_func
*
_aes_decrypt_vec
=
_aes_decrypt_init
;
/* This function should usually be called only once, at startup. But
it is idempotent, and on x86, pointer updates are atomic, so
there's no danger if it is called simultaneously from multiple
threads. */
static
void
fat_init
(
void
)
{
static
volatile
int
initialized
=
0
;
uint32_t
cpuid_data
[
4
];
int
verbose
;
if
(
initialized
)
return
;
/* FIXME: Replace all getenv calls by getenv_secure? */
verbose
=
getenv
(
"NETTLE_FAT_VERBOSE"
)
!=
NULL
;
if
(
verbose
)
fprintf
(
stderr
,
"libnettle: fat library initialization.
\n
"
);
_nettle_cpuid
(
1
,
cpuid_data
);
if
(
verbose
)
fprintf
(
stderr
,
"libnettle: cpuid 1: %08x, %08x, %08x, %08x
\n
"
,
cpuid_data
[
0
],
cpuid_data
[
1
],
cpuid_data
[
2
],
cpuid_data
[
3
]);
if
(
cpuid_data
[
2
]
&
0x02000000
)
{
if
(
verbose
)
fprintf
(
stderr
,
"libnettle: aes instructions available.
\n
"
);
_aes_encrypt_vec
=
_nettle_aes_encrypt_aesni
;
_aes_decrypt_vec
=
_nettle_aes_decrypt_aesni
;
}
else
{
if
(
verbose
)
fprintf
(
stderr
,
"libnettle: aes instructions not available.
\n
"
);
_aes_encrypt_vec
=
_nettle_aes_encrypt_x86_64
;
_aes_decrypt_vec
=
_nettle_aes_decrypt_x86_64
;
}
/* FIXME: We ought to use some thread-aware memory barrier before
setting the initialized flag. For now, just do another cpuinfo
call to get some synchronization. */
_nettle_cpuid
(
1
,
cpuid_data
);
initialized
=
1
;
}
#if __GNUC__
static
void
__attribute__
((
constructor
))
fat_constructor
(
void
)
{
fat_init
();
}
#endif
#if HAVE_LINK_IFUNC
static
void_func
*
_aes_encrypt_resolve
(
void
)
{
if
(
getenv
(
"NETTLE_FAT_VERBOSE"
))
fprintf
(
stderr
,
"libnettle: _aes_encrypt_resolve
\n
"
);
fat_init
();
return
(
void_func
*
)
_aes_encrypt_vec
;
}
static
void_func
*
_aes_decrypt_resolve
(
void
)
{
if
(
getenv
(
"NETTLE_FAT_VERBOSE"
))
fprintf
(
stderr
,
"libnettle: _aes_decrypt_resolve
\n
"
);
fat_init
();
return
(
void_func
*
)
_aes_decrypt_vec
;
}
#else
/* !HAVE_LINK_IFUNC */
/* We need wrapper functions jumping via the function pointer. */
void
_aes_encrypt
(
unsigned
rounds
,
const
uint32_t
*
keys
,
const
struct
aes_table
*
T
,
size_t
length
,
uint8_t
*
dst
,
const
uint8_t
*
src
)
{
_aes_encrypt_vec
(
rounds
,
keys
,
T
,
length
,
dst
,
src
);
}
static
void
_aes_encrypt_init
(
unsigned
rounds
,
const
uint32_t
*
keys
,
const
struct
aes_table
*
T
,
size_t
length
,
uint8_t
*
dst
,
const
uint8_t
*
src
)
{
if
(
getenv
(
"NETTLE_FAT_VERBOSE"
))
fprintf
(
stderr
,
"libnettle: _aes_encrypt_init
\n
"
);
fat_init
();
assert
(
_aes_encrypt_vec
!=
_aes_encrypt_init
);
_aes_encrypt
(
rounds
,
keys
,
T
,
length
,
dst
,
src
);
}
void
_aes_decrypt
(
unsigned
rounds
,
const
uint32_t
*
keys
,
const
struct
aes_table
*
T
,
size_t
length
,
uint8_t
*
dst
,
const
uint8_t
*
src
)
{
_aes_decrypt_vec
(
rounds
,
keys
,
T
,
length
,
dst
,
src
);
}
static
void
_aes_decrypt_init
(
unsigned
rounds
,
const
uint32_t
*
keys
,
const
struct
aes_table
*
T
,
size_t
length
,
uint8_t
*
dst
,
const
uint8_t
*
src
)
{
if
(
getenv
(
"NETTLE_FAT_VERBOSE"
))
fprintf
(
stderr
,
"libnettle: _aes_decrypt_init
\n
"
);
fat_init
();
assert
(
_aes_decrypt_vec
!=
_aes_decrypt_init
);
_aes_decrypt
(
rounds
,
keys
,
T
,
length
,
dst
,
src
);
}
#endif
/* !HAVE_LINK_IFUNC */
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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