Commit e0a03ca3 authored by Sergei Golubchik's avatar Sergei Golubchik

ed25519 plugin: simplify the api

various ed25519/ref10 api simplifications for our specific use case
parent 7120118a
...@@ -10,13 +10,13 @@ ERROR HY000: Can't initialize function 'ed25519_password'; Authentication plugin ...@@ -10,13 +10,13 @@ ERROR HY000: Can't initialize function 'ed25519_password'; Authentication plugin
install soname 'auth_ed25519'; install soname 'auth_ed25519';
select ed25519_password("foo"); select ed25519_password("foo");
ed25519_password("foo") ed25519_password("foo")
NNJledu0Vmk+VAZyz5IvUt3g1lMuNb8GvgE6fFMvIOA vubFBzIrapbfHct1/J72dnUryz5VS7lA6XHH8sIx4TI
select ed25519_password("foobar"); select ed25519_password("foobar");
ed25519_password("foobar") ed25519_password("foobar")
LgZlMsxPDw66qLCfGWRu4IVKqzyAqlA1aXSZbax5maE qv2mG6HWCuy32Slb5xhV4THStewNz2VINVPbgk+XAJ8
select ed25519_password("foo bar"); select ed25519_password("foo bar");
ed25519_password("foo bar") ed25519_password("foo bar")
6EFKeQLw+p5Ovk8tD+tAi3Agyg7ItukdswOBpTB6f40 Y5fV74JAVRMOK2cdnUsYS+WW9sXaaL/o+6WGKOgqnzc
select ed25519_password(NULL); select ed25519_password(NULL);
ed25519_password(NULL) ed25519_password(NULL)
NULL NULL
...@@ -34,10 +34,10 @@ PLUGIN_LICENSE GPL ...@@ -34,10 +34,10 @@ PLUGIN_LICENSE GPL
LOAD_OPTION ON LOAD_OPTION ON
PLUGIN_MATURITY Beta PLUGIN_MATURITY Beta
PLUGIN_AUTH_VERSION 1.0-alpha PLUGIN_AUTH_VERSION 1.0-alpha
create user test1@localhost identified via ed25519 using 'XQNqhYzon4REkXYuuJ4r+9UKSgoNpljksmKLJbEXrgk'; create user test1@localhost identified via ed25519 using 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY';
show grants for test1@localhost; show grants for test1@localhost;
Grants for test1@localhost Grants for test1@localhost
GRANT USAGE ON *.* TO 'test1'@'localhost' IDENTIFIED VIA ed25519 USING 'XQNqhYzon4REkXYuuJ4r+9UKSgoNpljksmKLJbEXrgk' GRANT USAGE ON *.* TO 'test1'@'localhost' IDENTIFIED VIA ed25519 USING 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY'
connect(localhost,test1,public,test,PORT,SOCKET); connect(localhost,test1,public,test,PORT,SOCKET);
ERROR 28000: Access denied for user 'test1'@'localhost' (using password: YES) ERROR 28000: Access denied for user 'test1'@'localhost' (using password: YES)
select current_user(); select current_user();
......
...@@ -10,3 +10,18 @@ There are four ed25519 implementations in SUPERCOP, ref10 is faster then ref, ...@@ -10,3 +10,18 @@ There are four ed25519 implementations in SUPERCOP, ref10 is faster then ref,
and there are two that are even faster, written in amd64 assembler. and there are two that are even faster, written in amd64 assembler.
Benchmarks are here: https://bench.cr.yp.to/impl-sign/ed25519.html Benchmarks are here: https://bench.cr.yp.to/impl-sign/ed25519.html
==============================
MariaDB changes:
API functions were simplified to better fit our use case:
* crypto_sign_open() does not return the verified message, only the
result of the verification (passed/failed)
* no secret key is generated explicitly, user specified password is used
as a source of randomness instead (SHA512("user password")).
* lengths are not returned, where they're known in advance
(e.g. from crypto_sign()).
* crypto_sign() does not take the public key as an argument, but
generates it on the fly (we used to generate public key before
crypto_sign(), doing it internally avoids double work).
See the changes done in this commit.
...@@ -27,20 +27,16 @@ ...@@ -27,20 +27,16 @@
static int do_auth(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) static int do_auth(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
{ {
unsigned char sk[CRYPTO_SECRETKEYBYTES], pk[CRYPTO_PUBLICKEYBYTES];
unsigned char reply[CRYPTO_BYTES + NONCE_BYTES], *pkt; unsigned char reply[CRYPTO_BYTES + NONCE_BYTES], *pkt;
unsigned long long reply_len;
int pkt_len; int pkt_len;
/* compute keys */
pw_to_sk_and_pk(mysql->passwd, strlen(mysql->passwd), sk, pk);
/* read the nonce */ /* read the nonce */
if ((pkt_len= vio->read_packet(vio, &pkt)) != NONCE_BYTES) if ((pkt_len= vio->read_packet(vio, &pkt)) != NONCE_BYTES)
return CR_SERVER_HANDSHAKE_ERR; return CR_SERVER_HANDSHAKE_ERR;
/* sign the nonce */ /* sign the nonce */
crypto_sign(reply, &reply_len, pkt, NONCE_BYTES, sk); crypto_sign(reply, pkt, NONCE_BYTES,
(unsigned char*)mysql->passwd, strlen(mysql->passwd));
/* send the signature */ /* send the signature */
if (vio->write_packet(vio, reply, CRYPTO_BYTES)) if (vio->write_packet(vio, reply, CRYPTO_BYTES))
......
...@@ -19,14 +19,5 @@ ...@@ -19,14 +19,5 @@
#include "ref10/api.h" #include "ref10/api.h"
#include "crypto_sign.h" #include "crypto_sign.h"
#include "crypto_hash_sha256.h"
#define NONCE_BYTES 32 #define NONCE_BYTES 32
static inline void pw_to_sk_and_pk(const char *pw, size_t pwlen,
unsigned char *sk, unsigned char *pk)
{
crypto_hash_sha256(sk, pw, pwlen);
crypto_sign_keypair(pk, sk);
}
#include <mysql/service_sha2.h>
#define crypto_hash_sha256(DST,SRC,SLEN) my_sha256(DST,(char*)(SRC),SLEN)
int crypto_sign_keypair(unsigned char *pk,unsigned char *sk); int crypto_sign_keypair(
unsigned char *pk,
unsigned char *pw, unsigned long long pwlen
);
int crypto_sign( int crypto_sign(
unsigned char *sm, unsigned long long *smlen, unsigned char *sm,
const unsigned char *m, unsigned long long mlen, const unsigned char *m, unsigned long long mlen,
const unsigned char *sk const unsigned char *pw, unsigned long long pwlen
); );
int crypto_sign_open( int crypto_sign_open(
unsigned char *m, unsigned long long *mlen, unsigned char *sm, unsigned long long smlen,
const unsigned char *sm, unsigned long long smlen,
const unsigned char *pk const unsigned char *pk
); );
...@@ -20,38 +20,35 @@ ...@@ -20,38 +20,35 @@
int main() int main()
{ {
uchar sk[CRYPTO_SECRETKEYBYTES], pk[CRYPTO_PUBLICKEYBYTES]; uchar pk[CRYPTO_PUBLICKEYBYTES];
uchar foobar_sk[CRYPTO_SECRETKEYBYTES]= {195, 171, 143, 241, 55, 32, 232, uchar foobar_pk[CRYPTO_PUBLICKEYBYTES]= {170, 253, 166, 27, 161, 214, 10,
173, 144, 71, 221, 57, 70, 107, 60, 137, 116, 229, 146, 194, 250, 56, 61, 236, 183, 217, 41, 91, 231, 24, 85, 225, 49, 210, 181, 236, 13, 207, 101,
74, 57, 96, 113, 76, 174, 240, 196, 242, 46, 6, 101, 50, 204, 79, 15, 14, 72, 53, 83, 219, 130, 79, 151, 0, 159};
186, 168, 176, 159, 25, 100, 110, 224, 133, 74, 171, 60, 128, 170, 80, 53, uchar foobar_sign[CRYPTO_BYTES]= {232, 61, 201, 63, 67, 63, 51, 53, 86, 73,
105, 116, 153, 109, 172, 121, 153, 161}; 238, 35, 170, 117, 146, 214, 26, 17, 35, 9, 8, 132, 245, 141, 48, 99, 66,
uchar foobar_sign[CRYPTO_BYTES]= {164, 116, 168, 41, 250, 169, 91, 205, 126, 58, 36, 228, 48, 84, 115, 254, 187, 168, 88, 162, 249, 57, 35, 85, 79, 238,
71, 253, 70, 233, 228, 79, 70, 43, 157, 221, 169, 35, 130, 101, 62, 133, 167, 106, 68, 117, 56, 135, 171, 47, 20, 14, 133, 79, 15, 229, 124, 160,
50, 104, 50, 45, 168, 238, 198, 48, 243, 76, 167, 173, 56, 241, 81, 221, 176, 100, 138, 14};
197, 31, 60, 247, 225, 52, 158, 31, 82, 20, 6, 237, 68, 54, 32, 78, 244,
91, 49, 194, 238, 117, 5 };
uchar nonce[NONCE_BYTES]; uchar nonce[NONCE_BYTES];
uchar reply[NONCE_BYTES+CRYPTO_BYTES]; uchar reply[NONCE_BYTES+CRYPTO_BYTES];
unsigned long long reply_len, scramble_len;
int r; int r;
plan(6); plan(4);
pw_to_sk_and_pk(STRING_WITH_LEN("foobar"), sk, pk);
ok(!memcmp(sk, foobar_sk, CRYPTO_SECRETKEYBYTES), "foobar sk"); crypto_sign_keypair(pk, USTRING_WITH_LEN("foobar"));
ok(!memcmp(pk, foobar_pk, CRYPTO_PUBLICKEYBYTES), "foobar pk");
memset(nonce, 'A', sizeof(nonce)); memset(nonce, 'A', sizeof(nonce));
crypto_sign(reply, &reply_len, nonce, sizeof(nonce), sk); crypto_sign(reply, nonce, sizeof(nonce), USTRING_WITH_LEN("foobar"));
ok(reply_len == sizeof(reply), "reply_len");
ok(!memcmp(reply, foobar_sign, CRYPTO_BYTES), "foobar sign"); ok(!memcmp(reply, foobar_sign, CRYPTO_BYTES), "foobar sign");
r= crypto_sign_open(nonce, &scramble_len, reply, reply_len, pk); r= crypto_sign_open(reply, sizeof(reply), pk);
ok(scramble_len == sizeof(nonce), "scramble_len");
ok(!r, "good nonce"); ok(!r, "good nonce");
crypto_sign(reply, nonce, sizeof(nonce), USTRING_WITH_LEN("foobar"));
reply[CRYPTO_BYTES + 10]='B'; reply[CRYPTO_BYTES + 10]='B';
r= crypto_sign_open(nonce, &scramble_len, reply, reply_len, pk); r= crypto_sign_open(reply, sizeof(reply), pk);
ok(r, "bad nonce"); ok(r, "bad nonce");
return exit_status(); return exit_status();
......
#define randombytes(BUF,LEN) /* no-op */
#define CRYPTO_SECRETKEYBYTES 64
#define CRYPTO_PUBLICKEYBYTES 32 #define CRYPTO_PUBLICKEYBYTES 32
#define CRYPTO_BYTES 64 #define CRYPTO_BYTES 64
#define CRYPTO_DETERMINISTIC 1 #define CRYPTO_DETERMINISTIC 1
#include <string.h> #include <string.h>
#include "randombytes.h"
#include "crypto_sign.h" #include "crypto_sign.h"
#include "crypto_hash_sha512.h" #include "crypto_hash_sha512.h"
#include "ge.h" #include "ge.h"
int crypto_sign_keypair(unsigned char *pk,unsigned char *sk) int crypto_sign_keypair(
unsigned char *pk,
unsigned char *pw, unsigned long long pwlen
)
{ {
unsigned char az[64]; unsigned char az[64];
ge_p3 A; ge_p3 A;
randombytes(sk,32); crypto_hash_sha512(az,pw,pwlen);
crypto_hash_sha512(az,sk,32);
az[0] &= 248; az[0] &= 248;
az[31] &= 63; az[31] &= 63;
az[31] |= 64; az[31] |= 64;
...@@ -18,6 +19,5 @@ int crypto_sign_keypair(unsigned char *pk,unsigned char *sk) ...@@ -18,6 +19,5 @@ int crypto_sign_keypair(unsigned char *pk,unsigned char *sk)
ge_scalarmult_base(&A,az); ge_scalarmult_base(&A,az);
ge_p3_tobytes(pk,&A); ge_p3_tobytes(pk,&A);
memmove(sk + 32,pk,32);
return 0; return 0;
} }
...@@ -6,13 +6,10 @@ ...@@ -6,13 +6,10 @@
#include "sc.h" #include "sc.h"
int crypto_sign_open( int crypto_sign_open(
unsigned char *m,unsigned long long *mlen, unsigned char *sm, unsigned long long smlen,
const unsigned char *sm,unsigned long long smlen,
const unsigned char *pk const unsigned char *pk
) )
{ {
unsigned char pkcopy[32];
unsigned char rcopy[32];
unsigned char scopy[32]; unsigned char scopy[32];
unsigned char h[64]; unsigned char h[64];
unsigned char rcheck[32]; unsigned char rcheck[32];
...@@ -23,26 +20,17 @@ int crypto_sign_open( ...@@ -23,26 +20,17 @@ int crypto_sign_open(
if (sm[63] & 224) goto badsig; if (sm[63] & 224) goto badsig;
if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig;
memmove(pkcopy,pk,32);
memmove(rcopy,sm,32);
memmove(scopy,sm + 32,32); memmove(scopy,sm + 32,32);
memmove(m,sm,smlen); memmove(sm + 32,pk,32);
memmove(m + 32,pkcopy,32); crypto_hash_sha512(h,sm,smlen);
crypto_hash_sha512(h,m,smlen);
sc_reduce(h); sc_reduce(h);
ge_double_scalarmult_vartime(&R,h,&A,scopy); ge_double_scalarmult_vartime(&R,h,&A,scopy);
ge_tobytes(rcheck,&R); ge_tobytes(rcheck,&R);
if (crypto_verify_32(rcheck,rcopy) == 0) { if (crypto_verify_32(rcheck,sm) == 0)
memmove(m,m + 64,smlen - 64);
memset(m + smlen - 64,0,64);
*mlen = smlen - 64;
return 0; return 0;
}
badsig: badsig:
*mlen = -1;
memset(m,0,smlen);
return -1; return -1;
} }
...@@ -5,29 +5,27 @@ ...@@ -5,29 +5,27 @@
#include "sc.h" #include "sc.h"
int crypto_sign( int crypto_sign(
unsigned char *sm,unsigned long long *smlen, unsigned char *sm,
const unsigned char *m,unsigned long long mlen, const unsigned char *m,unsigned long long mlen,
const unsigned char *sk const unsigned char *pw,unsigned long long pwlen
) )
{ {
unsigned char pk[32];
unsigned char az[64]; unsigned char az[64];
unsigned char nonce[64]; unsigned char nonce[64];
unsigned char hram[64]; unsigned char hram[64];
ge_p3 R; ge_p3 A, R;
memmove(pk,sk + 32,32); crypto_hash_sha512(az,pw,pwlen);
crypto_hash_sha512(az,sk,32);
az[0] &= 248; az[0] &= 248;
az[31] &= 63; az[31] &= 63;
az[31] |= 64; az[31] |= 64;
*smlen = mlen + 64;
memmove(sm + 64,m,mlen); memmove(sm + 64,m,mlen);
memmove(sm + 32,az + 32,32); memmove(sm + 32,az + 32,32);
crypto_hash_sha512(nonce,sm + 32,mlen + 32); crypto_hash_sha512(nonce,sm + 32,mlen + 32);
memmove(sm + 32,pk,32);
ge_scalarmult_base(&A,az);
ge_p3_tobytes(sm + 32,&A);
sc_reduce(nonce); sc_reduce(nonce);
ge_scalarmult_base(&R,nonce); ge_scalarmult_base(&R,nonce);
......
...@@ -33,11 +33,10 @@ static int loaded= 0; ...@@ -33,11 +33,10 @@ static int loaded= 0;
static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
{ {
unsigned long long out_len;
unsigned int i; unsigned int i;
int pkt_len; int pkt_len;
unsigned long nonce[CRYPTO_LONGS + NONCE_LONGS]; unsigned long nonce[CRYPTO_LONGS + NONCE_LONGS];
unsigned char *pkt, *reply= (unsigned char*)nonce, out[NONCE_BYTES]; unsigned char *pkt, *reply= (unsigned char*)nonce;
unsigned char pk[PASSWORD_LEN_BUF/4*3]; unsigned char pk[PASSWORD_LEN_BUF/4*3];
char pw[PASSWORD_LEN_BUF]; char pw[PASSWORD_LEN_BUF];
...@@ -64,7 +63,7 @@ static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) ...@@ -64,7 +63,7 @@ static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
return CR_AUTH_HANDSHAKE; return CR_AUTH_HANDSHAKE;
memcpy(reply, pkt, CRYPTO_BYTES); memcpy(reply, pkt, CRYPTO_BYTES);
if (crypto_sign_open(out, &out_len, reply, CRYPTO_BYTES + NONCE_BYTES, pk)) if (crypto_sign_open(reply, CRYPTO_BYTES + NONCE_BYTES, pk))
return CR_ERROR; return CR_ERROR;
return CR_OK; return CR_OK;
...@@ -113,14 +112,14 @@ char *ed25519_password(UDF_INIT *initid __attribute__((unused)), ...@@ -113,14 +112,14 @@ char *ed25519_password(UDF_INIT *initid __attribute__((unused)),
UDF_ARGS *args, char *result, unsigned long *length, UDF_ARGS *args, char *result, unsigned long *length,
char *is_null, char *error __attribute__((unused))) char *is_null, char *error __attribute__((unused)))
{ {
unsigned char sk[CRYPTO_SECRETKEYBYTES], pk[CRYPTO_PUBLICKEYBYTES]; unsigned char pk[CRYPTO_PUBLICKEYBYTES];
if ((*is_null= !args->args[0])) if ((*is_null= !args->args[0]))
return NULL; return NULL;
*length= PASSWORD_LEN; *length= PASSWORD_LEN;
pw_to_sk_and_pk(args->args[0], args->lengths[0], sk, pk); crypto_sign_keypair(pk, (unsigned char*)args->args[0], args->lengths[0]);
base64_encode(pk, sizeof(pk), result); base64_encode(pk, CRYPTO_PUBLICKEYBYTES, result);
return result; return result;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment