[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bug in ed25519 implementation


Hi

We discovered a compiler-dependent bug in the ed25519 implementation
that took us two days to find, but is trivial to fix. With one of our
compilers, if the server provided an ed25519 key, signature verification
failed.

The issue is the global variable at include/libssh/ge25519.h:31
> const ge25519 ge25519_base;
and is fixed by adding the extern keyword:
> extern const ge25519 ge25519_base;
(I did not bother creating a patch for this trivial change. ;-))

Explanation:
The global variable "ge25519_base" is referenced in the module
"src/external/ed25519.c" and initialized in "src/external/ge25519.c".
The lack of the extern keyword in the header results in different
instances being compiled into both translation units if compiled with a
standard-compliant compiler (XLC in our case). The instance in
"ge25519.o" is properly initialized, but the one in "ed25519.o" is
zeroed out. As a result, the zeroed version from "ed25519.o" is used to
attempt to verify the server's signature which obviously fails.

GCC and clang support a GNU extension for variables in global scope that
lack the extern keyword and which are not initialized within the
translation unit. If the linker finds an initialized version in another
translation unit, it is used, the zeroed version otherwise. In other
words, the extern keyword is implied by compilers implementing this
extension, which you obviously cannot rely on on non-GNU compilers.

This issue has already been fixed a while ago in OpenSSH and other projects.

Regards
Tilo

Follow-Ups:
Re: Bug in ed25519 implementationAndreas Schneider <asn@xxxxxxxxxxxxxx>
Archive administrator: postmaster@lists.cynapses.org