mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
ed25519 plugin: simplify the api
various ed25519/ref10 api simplifications for our specific use case
This commit is contained in:
parent
7120118a5e
commit
e0a03ca30a
13 changed files with 67 additions and 85 deletions
|
@ -10,13 +10,13 @@ ERROR HY000: Can't initialize function 'ed25519_password'; Authentication plugin
|
|||
install soname 'auth_ed25519';
|
||||
select ed25519_password("foo");
|
||||
ed25519_password("foo")
|
||||
NNJledu0Vmk+VAZyz5IvUt3g1lMuNb8GvgE6fFMvIOA
|
||||
vubFBzIrapbfHct1/J72dnUryz5VS7lA6XHH8sIx4TI
|
||||
select ed25519_password("foobar");
|
||||
ed25519_password("foobar")
|
||||
LgZlMsxPDw66qLCfGWRu4IVKqzyAqlA1aXSZbax5maE
|
||||
qv2mG6HWCuy32Slb5xhV4THStewNz2VINVPbgk+XAJ8
|
||||
select ed25519_password("foo bar");
|
||||
ed25519_password("foo bar")
|
||||
6EFKeQLw+p5Ovk8tD+tAi3Agyg7ItukdswOBpTB6f40
|
||||
Y5fV74JAVRMOK2cdnUsYS+WW9sXaaL/o+6WGKOgqnzc
|
||||
select ed25519_password(NULL);
|
||||
ed25519_password(NULL)
|
||||
NULL
|
||||
|
@ -34,10 +34,10 @@ PLUGIN_LICENSE GPL
|
|||
LOAD_OPTION ON
|
||||
PLUGIN_MATURITY Beta
|
||||
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;
|
||||
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);
|
||||
ERROR 28000: Access denied for user 'test1'@'localhost' (using password: YES)
|
||||
select current_user();
|
||||
|
|
|
@ -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.
|
||||
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 @@
|
|||
|
||||
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 long long reply_len;
|
||||
int pkt_len;
|
||||
|
||||
/* compute keys */
|
||||
pw_to_sk_and_pk(mysql->passwd, strlen(mysql->passwd), sk, pk);
|
||||
|
||||
/* read the nonce */
|
||||
if ((pkt_len= vio->read_packet(vio, &pkt)) != NONCE_BYTES)
|
||||
return CR_SERVER_HANDSHAKE_ERR;
|
||||
|
||||
/* 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 */
|
||||
if (vio->write_packet(vio, reply, CRYPTO_BYTES))
|
||||
|
|
|
@ -19,14 +19,5 @@
|
|||
|
||||
#include "ref10/api.h"
|
||||
#include "crypto_sign.h"
|
||||
#include "crypto_hash_sha256.h"
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
#include <mysql/service_sha2.h>
|
||||
#define crypto_hash_sha256(DST,SRC,SLEN) my_sha256(DST,(char*)(SRC),SLEN)
|
|
@ -1,11 +1,13 @@
|
|||
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(
|
||||
unsigned char *sm, unsigned long long *smlen,
|
||||
unsigned char *sm,
|
||||
const unsigned char *m, unsigned long long mlen,
|
||||
const unsigned char *sk
|
||||
const unsigned char *pw, unsigned long long pwlen
|
||||
);
|
||||
int crypto_sign_open(
|
||||
unsigned char *m, unsigned long long *mlen,
|
||||
const unsigned char *sm, unsigned long long smlen,
|
||||
unsigned char *sm, unsigned long long smlen,
|
||||
const unsigned char *pk
|
||||
);
|
||||
|
|
|
@ -20,38 +20,35 @@
|
|||
|
||||
int main()
|
||||
{
|
||||
uchar sk[CRYPTO_SECRETKEYBYTES], pk[CRYPTO_PUBLICKEYBYTES];
|
||||
uchar foobar_sk[CRYPTO_SECRETKEYBYTES]= {195, 171, 143, 241, 55, 32, 232,
|
||||
173, 144, 71, 221, 57, 70, 107, 60, 137, 116, 229, 146, 194, 250, 56, 61,
|
||||
74, 57, 96, 113, 76, 174, 240, 196, 242, 46, 6, 101, 50, 204, 79, 15, 14,
|
||||
186, 168, 176, 159, 25, 100, 110, 224, 133, 74, 171, 60, 128, 170, 80, 53,
|
||||
105, 116, 153, 109, 172, 121, 153, 161};
|
||||
uchar foobar_sign[CRYPTO_BYTES]= {164, 116, 168, 41, 250, 169, 91, 205, 126,
|
||||
71, 253, 70, 233, 228, 79, 70, 43, 157, 221, 169, 35, 130, 101, 62, 133,
|
||||
50, 104, 50, 45, 168, 238, 198, 48, 243, 76, 167, 173, 56, 241, 81, 221,
|
||||
197, 31, 60, 247, 225, 52, 158, 31, 82, 20, 6, 237, 68, 54, 32, 78, 244,
|
||||
91, 49, 194, 238, 117, 5 };
|
||||
uchar pk[CRYPTO_PUBLICKEYBYTES];
|
||||
uchar foobar_pk[CRYPTO_PUBLICKEYBYTES]= {170, 253, 166, 27, 161, 214, 10,
|
||||
236, 183, 217, 41, 91, 231, 24, 85, 225, 49, 210, 181, 236, 13, 207, 101,
|
||||
72, 53, 83, 219, 130, 79, 151, 0, 159};
|
||||
uchar foobar_sign[CRYPTO_BYTES]= {232, 61, 201, 63, 67, 63, 51, 53, 86, 73,
|
||||
238, 35, 170, 117, 146, 214, 26, 17, 35, 9, 8, 132, 245, 141, 48, 99, 66,
|
||||
58, 36, 228, 48, 84, 115, 254, 187, 168, 88, 162, 249, 57, 35, 85, 79, 238,
|
||||
167, 106, 68, 117, 56, 135, 171, 47, 20, 14, 133, 79, 15, 229, 124, 160,
|
||||
176, 100, 138, 14};
|
||||
|
||||
uchar nonce[NONCE_BYTES];
|
||||
uchar reply[NONCE_BYTES+CRYPTO_BYTES];
|
||||
unsigned long long reply_len, scramble_len;
|
||||
int r;
|
||||
|
||||
plan(6);
|
||||
pw_to_sk_and_pk(STRING_WITH_LEN("foobar"), sk, pk);
|
||||
ok(!memcmp(sk, foobar_sk, CRYPTO_SECRETKEYBYTES), "foobar sk");
|
||||
plan(4);
|
||||
|
||||
crypto_sign_keypair(pk, USTRING_WITH_LEN("foobar"));
|
||||
ok(!memcmp(pk, foobar_pk, CRYPTO_PUBLICKEYBYTES), "foobar pk");
|
||||
|
||||
memset(nonce, 'A', sizeof(nonce));
|
||||
crypto_sign(reply, &reply_len, nonce, sizeof(nonce), sk);
|
||||
ok(reply_len == sizeof(reply), "reply_len");
|
||||
crypto_sign(reply, nonce, sizeof(nonce), USTRING_WITH_LEN("foobar"));
|
||||
ok(!memcmp(reply, foobar_sign, CRYPTO_BYTES), "foobar sign");
|
||||
|
||||
r= crypto_sign_open(nonce, &scramble_len, reply, reply_len, pk);
|
||||
ok(scramble_len == sizeof(nonce), "scramble_len");
|
||||
r= crypto_sign_open(reply, sizeof(reply), pk);
|
||||
ok(!r, "good nonce");
|
||||
|
||||
crypto_sign(reply, nonce, sizeof(nonce), USTRING_WITH_LEN("foobar"));
|
||||
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");
|
||||
|
||||
return exit_status();
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#define randombytes(BUF,LEN) /* no-op */
|
|
@ -1,4 +1,3 @@
|
|||
#define CRYPTO_SECRETKEYBYTES 64
|
||||
#define CRYPTO_PUBLICKEYBYTES 32
|
||||
#define CRYPTO_BYTES 64
|
||||
#define CRYPTO_DETERMINISTIC 1
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
#include <string.h>
|
||||
#include "randombytes.h"
|
||||
#include "crypto_sign.h"
|
||||
#include "crypto_hash_sha512.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];
|
||||
ge_p3 A;
|
||||
|
||||
randombytes(sk,32);
|
||||
crypto_hash_sha512(az,sk,32);
|
||||
crypto_hash_sha512(az,pw,pwlen);
|
||||
az[0] &= 248;
|
||||
az[31] &= 63;
|
||||
az[31] |= 64;
|
||||
|
@ -18,6 +19,5 @@ int crypto_sign_keypair(unsigned char *pk,unsigned char *sk)
|
|||
ge_scalarmult_base(&A,az);
|
||||
ge_p3_tobytes(pk,&A);
|
||||
|
||||
memmove(sk + 32,pk,32);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -6,13 +6,10 @@
|
|||
#include "sc.h"
|
||||
|
||||
int crypto_sign_open(
|
||||
unsigned char *m,unsigned long long *mlen,
|
||||
const unsigned char *sm,unsigned long long smlen,
|
||||
unsigned char *sm, unsigned long long smlen,
|
||||
const unsigned char *pk
|
||||
)
|
||||
{
|
||||
unsigned char pkcopy[32];
|
||||
unsigned char rcopy[32];
|
||||
unsigned char scopy[32];
|
||||
unsigned char h[64];
|
||||
unsigned char rcheck[32];
|
||||
|
@ -23,26 +20,17 @@ int crypto_sign_open(
|
|||
if (sm[63] & 224) 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(m,sm,smlen);
|
||||
memmove(m + 32,pkcopy,32);
|
||||
crypto_hash_sha512(h,m,smlen);
|
||||
memmove(sm + 32,pk,32);
|
||||
crypto_hash_sha512(h,sm,smlen);
|
||||
sc_reduce(h);
|
||||
|
||||
ge_double_scalarmult_vartime(&R,h,&A,scopy);
|
||||
ge_tobytes(rcheck,&R);
|
||||
if (crypto_verify_32(rcheck,rcopy) == 0) {
|
||||
memmove(m,m + 64,smlen - 64);
|
||||
memset(m + smlen - 64,0,64);
|
||||
*mlen = smlen - 64;
|
||||
if (crypto_verify_32(rcheck,sm) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
badsig:
|
||||
*mlen = -1;
|
||||
memset(m,0,smlen);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -5,29 +5,27 @@
|
|||
#include "sc.h"
|
||||
|
||||
int crypto_sign(
|
||||
unsigned char *sm,unsigned long long *smlen,
|
||||
unsigned char *sm,
|
||||
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 nonce[64];
|
||||
unsigned char hram[64];
|
||||
ge_p3 R;
|
||||
ge_p3 A, R;
|
||||
|
||||
memmove(pk,sk + 32,32);
|
||||
|
||||
crypto_hash_sha512(az,sk,32);
|
||||
crypto_hash_sha512(az,pw,pwlen);
|
||||
az[0] &= 248;
|
||||
az[31] &= 63;
|
||||
az[31] |= 64;
|
||||
|
||||
*smlen = mlen + 64;
|
||||
memmove(sm + 64,m,mlen);
|
||||
memmove(sm + 32,az + 32,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);
|
||||
ge_scalarmult_base(&R,nonce);
|
||||
|
|
|
@ -33,11 +33,10 @@ static int loaded= 0;
|
|||
|
||||
static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
|
||||
{
|
||||
unsigned long long out_len;
|
||||
unsigned int i;
|
||||
int pkt_len;
|
||||
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];
|
||||
char pw[PASSWORD_LEN_BUF];
|
||||
|
||||
|
@ -64,7 +63,7 @@ static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
|
|||
return CR_AUTH_HANDSHAKE;
|
||||
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_OK;
|
||||
|
@ -113,14 +112,14 @@ char *ed25519_password(UDF_INIT *initid __attribute__((unused)),
|
|||
UDF_ARGS *args, char *result, unsigned long *length,
|
||||
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]))
|
||||
return NULL;
|
||||
|
||||
*length= PASSWORD_LEN;
|
||||
pw_to_sk_and_pk(args->args[0], args->lengths[0], sk, pk);
|
||||
base64_encode(pk, sizeof(pk), result);
|
||||
crypto_sign_keypair(pk, (unsigned char*)args->args[0], args->lengths[0]);
|
||||
base64_encode(pk, CRYPTO_PUBLICKEYBYTES, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue