Skip to content

Commit 7120118

Browse files
committed
MDEV-12160 Modern alternative to the SHA1 authentication plugin
ED25519 authentication plugin
1 parent 269ab56 commit 7120118

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+5124
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
create function ed25519_password returns string soname "auth_ed25519.so";
2+
select ed25519_password();
3+
ERROR HY000: Can't initialize function 'ed25519_password'; Wrong arguments to ed25519_password()
4+
select ed25519_password(1);
5+
ERROR HY000: Can't initialize function 'ed25519_password'; Wrong arguments to ed25519_password()
6+
select ed25519_password("foo", "bar");
7+
ERROR HY000: Can't initialize function 'ed25519_password'; Wrong arguments to ed25519_password()
8+
select ed25519_password("foo");
9+
ERROR HY000: Can't initialize function 'ed25519_password'; Authentication plugin ed25519 is not loaded
10+
install soname 'auth_ed25519';
11+
select ed25519_password("foo");
12+
ed25519_password("foo")
13+
NNJledu0Vmk+VAZyz5IvUt3g1lMuNb8GvgE6fFMvIOA
14+
select ed25519_password("foobar");
15+
ed25519_password("foobar")
16+
LgZlMsxPDw66qLCfGWRu4IVKqzyAqlA1aXSZbax5maE
17+
select ed25519_password("foo bar");
18+
ed25519_password("foo bar")
19+
6EFKeQLw+p5Ovk8tD+tAi3Agyg7ItukdswOBpTB6f40
20+
select ed25519_password(NULL);
21+
ed25519_password(NULL)
22+
NULL
23+
select * from information_schema.plugins where plugin_name='ed25519';
24+
PLUGIN_NAME ed25519
25+
PLUGIN_VERSION 1.0
26+
PLUGIN_STATUS ACTIVE
27+
PLUGIN_TYPE AUTHENTICATION
28+
PLUGIN_TYPE_VERSION 2.1
29+
PLUGIN_LIBRARY auth_ed25519.so
30+
PLUGIN_LIBRARY_VERSION 1.12
31+
PLUGIN_AUTHOR Sergei Golubchik
32+
PLUGIN_DESCRIPTION Elliptic curve ED25519 based authentication
33+
PLUGIN_LICENSE GPL
34+
LOAD_OPTION ON
35+
PLUGIN_MATURITY Beta
36+
PLUGIN_AUTH_VERSION 1.0-alpha
37+
create user test1@localhost identified via ed25519 using 'XQNqhYzon4REkXYuuJ4r+9UKSgoNpljksmKLJbEXrgk';
38+
show grants for test1@localhost;
39+
Grants for test1@localhost
40+
GRANT USAGE ON *.* TO 'test1'@'localhost' IDENTIFIED VIA ed25519 USING 'XQNqhYzon4REkXYuuJ4r+9UKSgoNpljksmKLJbEXrgk'
41+
connect(localhost,test1,public,test,PORT,SOCKET);
42+
ERROR 28000: Access denied for user 'test1'@'localhost' (using password: YES)
43+
select current_user();
44+
current_user()
45+
test1@localhost
46+
drop user test1@localhost;
47+
uninstall plugin ed25519;
48+
select ed25519_password("foo");
49+
ERROR HY000: Can't initialize function 'ed25519_password'; Authentication plugin ed25519 is not loaded
50+
drop function ed25519_password;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#
2+
# MDEV-12160 Modern alternative to the SHA1 authentication plugin
3+
#
4+
source include/not_embedded.inc;
5+
if (!$AUTH_ED25519_SO) {
6+
skip No auth_ed25519 plugin;
7+
}
8+
9+
replace_result dll so;
10+
eval create function ed25519_password returns string soname "$AUTH_ED25519_SO";
11+
error ER_CANT_INITIALIZE_UDF;
12+
select ed25519_password();
13+
error ER_CANT_INITIALIZE_UDF;
14+
select ed25519_password(1);
15+
error ER_CANT_INITIALIZE_UDF;
16+
select ed25519_password("foo", "bar");
17+
error ER_CANT_INITIALIZE_UDF;
18+
select ed25519_password("foo");
19+
20+
install soname 'auth_ed25519';
21+
select ed25519_password("foo");
22+
select ed25519_password("foobar");
23+
select ed25519_password("foo bar");
24+
select ed25519_password(NULL);
25+
26+
replace_result dll so;
27+
query_vertical select * from information_schema.plugins where plugin_name='ed25519';
28+
let $pwd=`select ed25519_password("secret")`;
29+
eval create user test1@localhost identified via ed25519 using '$pwd';
30+
show grants for test1@localhost;
31+
32+
replace_result $MASTER_MYPORT PORT $MASTER_MYSOCK SOCKET;
33+
error ER_ACCESS_DENIED_ERROR;
34+
connect con1, localhost, test1, public;
35+
connect con1, localhost, test1, secret;
36+
select current_user();
37+
disconnect con1;
38+
connection default;
39+
40+
drop user test1@localhost;
41+
uninstall plugin ed25519;
42+
error ER_CANT_INITIALIZE_UDF;
43+
select ed25519_password("foo");
44+
drop function ed25519_password;

plugin/auth_ed25519/CMakeLists.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
SET(REF10_SOURCES
2+
ref10/fe_0.c ref10/fe_1.c ref10/fe_add.c ref10/fe_cmov.c ref10/fe_copy.c
3+
ref10/fe_frombytes.c ref10/fe_invert.c ref10/fe_isnegative.c
4+
ref10/fe_isnonzero.c ref10/fe_mul.c ref10/fe_neg.c ref10/fe_pow22523.c
5+
ref10/fe_sq.c ref10/fe_sq2.c ref10/fe_sub.c ref10/fe_tobytes.c
6+
ref10/ge_add.c ref10/ge_double_scalarmult.c ref10/ge_frombytes.c
7+
ref10/ge_madd.c ref10/ge_msub.c ref10/ge_p1p1_to_p2.c
8+
ref10/ge_p1p1_to_p3.c ref10/ge_p2_0.c ref10/ge_p2_dbl.c ref10/ge_p3_0.c
9+
ref10/ge_p3_dbl.c ref10/ge_p3_to_cached.c ref10/ge_p3_to_p2.c
10+
ref10/ge_p3_tobytes.c ref10/ge_precomp_0.c ref10/ge_scalarmult_base.c
11+
ref10/ge_sub.c ref10/ge_tobytes.c ref10/keypair.c ref10/open.c
12+
ref10/sc_muladd.c ref10/sc_reduce.c ref10/sign.c ref10/verify.c)
13+
14+
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
15+
16+
ADD_CONVENIENCE_LIBRARY(ref10 ${REF10_SOURCES})
17+
18+
MYSQL_ADD_PLUGIN(auth_ed25519 server_ed25519.c ${REF10_SOURCES} MODULE_ONLY)
19+
20+
MYSQL_ADD_PLUGIN(client_ed25519 client_ed25519.c MODULE_ONLY
21+
CLIENT LINK_LIBRARIES mysys_ssl ref10 COMPONENT ClientPlugins)
22+
23+
IF(WITH_UNIT_TESTS)
24+
MY_ADD_TESTS(ed25519 LINK_LIBRARIES mysys ref10)
25+
ENDIF()

plugin/auth_ed25519/README

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
This plugin uses public domain ed25519 code
2+
by Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, Bo-Yin Yang.
3+
4+
It is "ref10" implementation from the SUPERCOP:
5+
https://bench.cr.yp.to/supercop.html
6+
7+
OpenSSH also uses ed25519 from SUPERCOP, but "ref" implementation.
8+
9+
There are four ed25519 implementations in SUPERCOP, ref10 is faster then ref,
10+
and there are two that are even faster, written in amd64 assembler.
11+
Benchmarks are here: https://bench.cr.yp.to/impl-sign/ed25519.html
12+

plugin/auth_ed25519/client_ed25519.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
Copyright (c) 2017, MariaDB
3+
4+
This program is free software; you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation; version 2 of the License.
7+
8+
This program is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
GNU General Public License for more details.
12+
13+
You should have received a copy of the GNU General Public License
14+
along with this program; if not, write to the Free Software
15+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16+
17+
/************************** CLIENT *************************************/
18+
19+
#include <stdlib.h>
20+
#include "common.h"
21+
#include <mysql/client_plugin.h>
22+
#include <errmsg.h>
23+
24+
#if !defined(__attribute__) && !defined(__GNUC__)
25+
#define __attribute__(A)
26+
#endif
27+
28+
static int do_auth(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
29+
{
30+
unsigned char sk[CRYPTO_SECRETKEYBYTES], pk[CRYPTO_PUBLICKEYBYTES];
31+
unsigned char reply[CRYPTO_BYTES + NONCE_BYTES], *pkt;
32+
unsigned long long reply_len;
33+
int pkt_len;
34+
35+
/* compute keys */
36+
pw_to_sk_and_pk(mysql->passwd, strlen(mysql->passwd), sk, pk);
37+
38+
/* read the nonce */
39+
if ((pkt_len= vio->read_packet(vio, &pkt)) != NONCE_BYTES)
40+
return CR_SERVER_HANDSHAKE_ERR;
41+
42+
/* sign the nonce */
43+
crypto_sign(reply, &reply_len, pkt, NONCE_BYTES, sk);
44+
45+
/* send the signature */
46+
if (vio->write_packet(vio, reply, CRYPTO_BYTES))
47+
return CR_ERROR;
48+
49+
return CR_OK;
50+
}
51+
52+
static int init_client(char *unused1 __attribute__((unused)),
53+
size_t unused2 __attribute__((unused)),
54+
int unused3 __attribute__((unused)),
55+
va_list unused4 __attribute__((unused)))
56+
{
57+
return 0;
58+
}
59+
60+
mysql_declare_client_plugin(AUTHENTICATION)
61+
"client_ed25519",
62+
"Sergei Golubchik",
63+
"Elliptic curve ED25519 based authentication",
64+
{0,1,0},
65+
"GPL",
66+
NULL,
67+
init_client,
68+
NULL,
69+
NULL,
70+
do_auth,
71+
mysql_end_client_plugin;
72+

plugin/auth_ed25519/common.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Copyright (c) 2017, MariaDB
3+
4+
This program is free software; you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation; version 2 of the License.
7+
8+
This program is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
GNU General Public License for more details.
12+
13+
You should have received a copy of the GNU General Public License
14+
along with this program; if not, write to the Free Software
15+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16+
17+
#include <mysql.h>
18+
#include <string.h>
19+
20+
#include "ref10/api.h"
21+
#include "crypto_sign.h"
22+
#include "crypto_hash_sha256.h"
23+
24+
#define NONCE_BYTES 32
25+
26+
static inline void pw_to_sk_and_pk(const char *pw, size_t pwlen,
27+
unsigned char *sk, unsigned char *pk)
28+
{
29+
crypto_hash_sha256(sk, pw, pwlen);
30+
crypto_sign_keypair(pk, sk);
31+
}
32+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include <mysql/service_sha2.h>
2+
#define crypto_hash_sha256(DST,SRC,SLEN) my_sha256(DST,(char*)(SRC),SLEN)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include <mysql/service_sha2.h>
2+
#define crypto_hash_sha512(DST,SRC,SLEN) my_sha512(DST,(char*)(SRC),SLEN)

plugin/auth_ed25519/crypto_int32.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include <stdint.h>
2+
#include <sys/types.h>
3+
typedef int32_t crypto_int32;
4+
5+
#define select ed25519_select

plugin/auth_ed25519/crypto_int64.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include <stdint.h>
2+
#include <sys/types.h>
3+
typedef int64_t crypto_int64;
4+
5+
#define select ed25519_select

0 commit comments

Comments
 (0)