From e0a03ca30aa6f91daf7ea519a57d85e54dc49927 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 6 Mar 2017 01:27:34 +0100 Subject: ed25519 plugin: simplify the api various ed25519/ref10 api simplifications for our specific use case --- plugin/auth_ed25519/README | 15 +++++++++++++ plugin/auth_ed25519/client_ed25519.c | 8 ++----- plugin/auth_ed25519/common.h | 9 -------- plugin/auth_ed25519/crypto_hash_sha256.h | 2 -- plugin/auth_ed25519/crypto_sign.h | 12 ++++++----- plugin/auth_ed25519/ed25519-t.c | 37 +++++++++++++++----------------- plugin/auth_ed25519/randombytes.h | 1 - plugin/auth_ed25519/ref10/api.h | 1 - plugin/auth_ed25519/ref10/keypair.c | 10 ++++----- plugin/auth_ed25519/ref10/open.c | 20 ++++------------- plugin/auth_ed25519/ref10/sign.c | 16 ++++++-------- plugin/auth_ed25519/server_ed25519.c | 11 +++++----- 12 files changed, 62 insertions(+), 80 deletions(-) delete mode 100644 plugin/auth_ed25519/crypto_hash_sha256.h delete mode 100644 plugin/auth_ed25519/randombytes.h (limited to 'plugin') diff --git a/plugin/auth_ed25519/README b/plugin/auth_ed25519/README index aa0263428f4..e65a33e6019 100644 --- a/plugin/auth_ed25519/README +++ b/plugin/auth_ed25519/README @@ -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. diff --git a/plugin/auth_ed25519/client_ed25519.c b/plugin/auth_ed25519/client_ed25519.c index 87ced2c74c2..1b7173fbc40 100644 --- a/plugin/auth_ed25519/client_ed25519.c +++ b/plugin/auth_ed25519/client_ed25519.c @@ -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)) diff --git a/plugin/auth_ed25519/common.h b/plugin/auth_ed25519/common.h index df317535d01..77f8699322c 100644 --- a/plugin/auth_ed25519/common.h +++ b/plugin/auth_ed25519/common.h @@ -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); -} - diff --git a/plugin/auth_ed25519/crypto_hash_sha256.h b/plugin/auth_ed25519/crypto_hash_sha256.h deleted file mode 100644 index 557b30b56dd..00000000000 --- a/plugin/auth_ed25519/crypto_hash_sha256.h +++ /dev/null @@ -1,2 +0,0 @@ -#include -#define crypto_hash_sha256(DST,SRC,SLEN) my_sha256(DST,(char*)(SRC),SLEN) diff --git a/plugin/auth_ed25519/crypto_sign.h b/plugin/auth_ed25519/crypto_sign.h index 20c96121723..e12a8c71f6e 100644 --- a/plugin/auth_ed25519/crypto_sign.h +++ b/plugin/auth_ed25519/crypto_sign.h @@ -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 ); diff --git a/plugin/auth_ed25519/ed25519-t.c b/plugin/auth_ed25519/ed25519-t.c index 7ce177a113e..f7d58c48d7c 100644 --- a/plugin/auth_ed25519/ed25519-t.c +++ b/plugin/auth_ed25519/ed25519-t.c @@ -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(); diff --git a/plugin/auth_ed25519/randombytes.h b/plugin/auth_ed25519/randombytes.h deleted file mode 100644 index 322454074ca..00000000000 --- a/plugin/auth_ed25519/randombytes.h +++ /dev/null @@ -1 +0,0 @@ -#define randombytes(BUF,LEN) /* no-op */ diff --git a/plugin/auth_ed25519/ref10/api.h b/plugin/auth_ed25519/ref10/api.h index d88dae0c32c..9f1db7e566a 100644 --- a/plugin/auth_ed25519/ref10/api.h +++ b/plugin/auth_ed25519/ref10/api.h @@ -1,4 +1,3 @@ -#define CRYPTO_SECRETKEYBYTES 64 #define CRYPTO_PUBLICKEYBYTES 32 #define CRYPTO_BYTES 64 #define CRYPTO_DETERMINISTIC 1 diff --git a/plugin/auth_ed25519/ref10/keypair.c b/plugin/auth_ed25519/ref10/keypair.c index ac6cea2b7af..64000838b5e 100644 --- a/plugin/auth_ed25519/ref10/keypair.c +++ b/plugin/auth_ed25519/ref10/keypair.c @@ -1,16 +1,17 @@ #include -#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; } diff --git a/plugin/auth_ed25519/ref10/open.c b/plugin/auth_ed25519/ref10/open.c index 1ec4cd2bfda..7362b681436 100644 --- a/plugin/auth_ed25519/ref10/open.c +++ b/plugin/auth_ed25519/ref10/open.c @@ -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; } diff --git a/plugin/auth_ed25519/ref10/sign.c b/plugin/auth_ed25519/ref10/sign.c index de53742a6ca..0cf1edd153d 100644 --- a/plugin/auth_ed25519/ref10/sign.c +++ b/plugin/auth_ed25519/ref10/sign.c @@ -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); diff --git a/plugin/auth_ed25519/server_ed25519.c b/plugin/auth_ed25519/server_ed25519.c index 25bed7d2336..e0eff64fa7d 100644 --- a/plugin/auth_ed25519/server_ed25519.c +++ b/plugin/auth_ed25519/server_ed25519.c @@ -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; } -- cgit v1.2.1