diff --git a/include/Makefile.am b/include/Makefile.am index a852e68..e597afc 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -5,4 +5,5 @@ nobase_include_HEADERS = sxmp/sxmp.h sxmp/errno.h sxmp/limits.h sxmp/version.h \ tdata/bitwise.h tdata/idx_allocator.h tdata/macro.h tdata/tree.h \ tdata/usrtc.h tdata/list.h tdata/ctrie.h \ ydaemon/ydaemon.h ydaemon/cache.h ydaemon/dataobject.h \ - sxt/sxtkey.h + sxt/sxtkey.h sxt/lcrypt.h sxt/fe25519.h sxt/ge25519.h \ + sxt/sc25519.h diff --git a/include/sxt/lcrypt.h b/include/sxt/lcrypt.h new file mode 100644 index 0000000..ee7557a --- /dev/null +++ b/include/sxt/lcrypt.h @@ -0,0 +1,45 @@ +/* + * Secure eXtended Message Passing framework + * Secure eXtended Transport layer implementation: (libsxt) + * - very similar to SSH2/TLS + * - using already proven and tested crypto algos + * - better than TLS for message passing + * + * Some useful wrappers and structures + * + * (c) Alexander Vdolainen 2016 + * + * libsxmp is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libsxmp is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see ."; + * + */ + +#ifndef __SXT_SXTCRYPT_H__ +#define __SXT_SXTCRYPT_H__ + +#include + +typedef SHA512_CTX* SHA512CTX; + +#define SHA512_DIGEST_LEN SHA512_DIGEST_LENGTH + +/* sxt wrapper around random numbers */ +int sxt_get_random(void *data, int len, int pseudo); + +/* wrappers around SHA512 */ +SHA512CTX sha512_init(void); +void sha512_update(SHA512CTX c, const void *data, unsigned long len); +void sha512_final(unsigned char *md, SHA512CTX c); + + +#endif diff --git a/include/sxt/sxtkey.h b/include/sxt/sxtkey.h index 04e2b6d..cb038da 100644 --- a/include/sxt/sxtkey.h +++ b/include/sxt/sxtkey.h @@ -47,4 +47,43 @@ typedef struct sxtkey_type { ed25519_privkey privkey; } sxtkey_t; +/* ed25519 related functions */ +/** @internal + * @brief generate an ed25519 key pair + * @param[out] pk generated public key + * @param[out] sk generated secret key + * @return 0 on success, -1 on error. + * */ +int crypto_sign_ed25519_keypair(ed25519_pubkey pk, ed25519_privkey sk); + +/** @internal + * @brief sign a message with ed25519 + * @param[out] sm location to store the signed message. + * Its length should be mlen + 64. + * @param[out] smlen pointer to the size of the signed message + * @param[in] m message to be signed + * @param[in] mlen length of the message to be signed + * @param[in] sk secret key to sign the message with + * @return 0 on success. + */ +int crypto_sign_ed25519(unsigned char *sm,unsigned long long *smlen, + const unsigned char *m,unsigned long long mlen, + const ed25519_privkey sk); + +/** @internal + * @brief "open" and verify the signature of a signed message + * @param[out] m location to store the verified message. + * Its length should be equal to smlen. + * @param[out] mlen pointer to the size of the verified message + * @param[in] sm signed message to verify + * @param[in] smlen length of the signed message to verify + * @param[in] pk public key used to sign the message + * @returns 0 on success (supposedly). + */ +int crypto_sign_ed25519_open(unsigned char *m,unsigned long long *mlen, + const unsigned char *sm,unsigned long long smlen, + const ed25519_pubkey pk); + +/** @} */ + #endif /* __SXT_SXTKEY_H__ */ diff --git a/sxt/Makefile.am b/sxt/Makefile.am index 9cffa81..30a92c0 100644 --- a/sxt/Makefile.am +++ b/sxt/Makefile.am @@ -14,7 +14,7 @@ lib_LTLIBRARIES = libsxt.la libsxt_la_SOURCES = \ - core.c + core.c ppkp_ops.c fe25519.c ge25519.c sc25519.c ed25519.c libsxt_la_LDFLAGS = diff --git a/sxt/core.c b/sxt/core.c index a1f2e01..d14cfe2 100644 --- a/sxt/core.c +++ b/sxt/core.c @@ -44,19 +44,56 @@ #include #endif +#if 0 #include #include #include +#endif +#include -#include #include +#include + int sxt_init(void) { - return; + return 0; } int sxt_finish(void) { - return; + return 0; +} + +int sxt_get_random(void *data, int len, int pseudo) +{ + if(pseudo) return RAND_bytes(data, len); + else +#if OPENSSL_API_COMPAT < 0x10100000L + RAND_pseudo_bytes(data, len); +#else + RAND_bytes(data, len); +#endif + + return 1; +} + +/* wrappers */ +SHA512CTX sha512_init(void){ + SHA512CTX c = malloc(sizeof(*c)); + if (c == NULL) { + return NULL; + } + SHA512_Init(c); + + return c; +} + +void sha512_update(SHA512CTX c, const void *data, unsigned long len){ + SHA512_Update(c,data,len); +} + +void sha512_final(unsigned char *md, SHA512CTX c) { + SHA512_Final(md, c); + if(c) free(c); } diff --git a/sxt/ed25519.c b/sxt/ed25519.c new file mode 100644 index 0000000..fb82b34 --- /dev/null +++ b/sxt/ed25519.c @@ -0,0 +1,219 @@ +/* + * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, + * Peter Schwabe, Bo-Yin Yang. + * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c + */ + +#include "config.h" + +#include +#include +#include +#include + +/* + * Public Domain, Author: Daniel J. Bernstein + * Copied from nacl-20110221/crypto_verify/32/ref/verify.c + */ + +static int crypto_verify_32(const unsigned char *x,const unsigned char *y) +{ + unsigned int differentbits = 0; +#define F(i) differentbits |= x[i] ^ y[i]; + F(0) + F(1) + F(2) + F(3) + F(4) + F(5) + F(6) + F(7) + F(8) + F(9) + F(10) + F(11) + F(12) + F(13) + F(14) + F(15) + F(16) + F(17) + F(18) + F(19) + F(20) + F(21) + F(22) + F(23) + F(24) + F(25) + F(26) + F(27) + F(28) + F(29) + F(30) + F(31) + + return (1 & ((differentbits - 1) >> 8)) - 1; +} + +static void get_hram(unsigned char *hram, + const unsigned char *sm, + const unsigned char *pk, + unsigned char *playground, + unsigned long long smlen) +{ + unsigned long long i; + SHA512CTX ctx; + for (i = 0;i < 32;++i) playground[i] = sm[i]; + for (i = 32;i < 64;++i) playground[i] = pk[i-32]; + for (i = 64;i < smlen;++i) playground[i] = sm[i]; + + ctx = sha512_init(); + sha512_update(ctx, playground, smlen); + sha512_final(hram, ctx); +} + + +int crypto_sign_ed25519_keypair(unsigned char *pk, + unsigned char *sk) +{ + sc25519 scsk; + ge25519 gepk; + SHA512CTX ctx; + unsigned char extsk[64]; + int i; + int rc; + + rc = sxt_get_random(sk, 32, 0); + if (rc < 0){ + return -1; + } + + ctx = sha512_init(); + sha512_update(ctx, sk, 32); + sha512_final(extsk, ctx); + extsk[0] &= 248; + extsk[31] &= 127; + extsk[31] |= 64; + + sc25519_from32bytes(&scsk,extsk); + + ge25519_scalarmult_base(&gepk, &scsk); + ge25519_pack(pk, &gepk); + for(i=0;i<32;i++) { + sk[32 + i] = pk[i]; + } + + return 0; +} + +int crypto_sign_ed25519(unsigned char *sm, + unsigned long long *smlen, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk) +{ + sc25519 sck, scs, scsk; + ge25519 ger; + SHA512CTX ctx; + unsigned char r[32]; + unsigned char s[32]; + unsigned char extsk[64]; + unsigned long long i; + unsigned char hmg[SHA512_DIGEST_LEN]; + unsigned char hram[SHA512_DIGEST_LEN]; + + ctx = sha512_init(); + sha512_update(ctx, sk, 32); + sha512_final(extsk, ctx); + + extsk[0] &= 248; + extsk[31] &= 127; + extsk[31] |= 64; + + *smlen = mlen + 64; + for (i = 0;i < mlen; i++) { + sm[64 + i] = m[i]; + } + for (i = 0;i < 32; i++) { + sm[32 + i] = extsk[32+i]; + } + + /* Generate k as h(extsk[32],...,extsk[63],m) */ + ctx = sha512_init(); + sha512_update(ctx, sm + 32, mlen + 32); + sha512_final(hmg, ctx); + + /* Computation of R */ + sc25519_from64bytes(&sck, hmg); + ge25519_scalarmult_base(&ger, &sck); + ge25519_pack(r, &ger); + + /* Computation of s */ + for (i = 0; i < 32; i++) { + sm[i] = r[i]; + } + + get_hram(hram, sm, sk+32, sm, mlen+64); + + sc25519_from64bytes(&scs, hram); + sc25519_from32bytes(&scsk, extsk); + sc25519_mul(&scs, &scs, &scsk); + + sc25519_add(&scs, &scs, &sck); + + sc25519_to32bytes(s,&scs); /* cat s */ + for (i = 0;i < 32; i++) { + sm[32 + i] = s[i]; + } + + return 0; +} + +int crypto_sign_ed25519_open(unsigned char *m, + unsigned long long *mlen, + const unsigned char *sm, + unsigned long long smlen, + const unsigned char *pk) +{ + unsigned int i; + int ret; + unsigned char t2[32]; + ge25519 get1, get2; + sc25519 schram, scs; + unsigned char hram[SHA512_DIGEST_LEN]; + + *mlen = (unsigned long long) -1; + if (smlen < 64) return -1; + + if (ge25519_unpackneg_vartime(&get1, pk)) { + return -1; + } + + get_hram(hram,sm,pk,m,smlen); + + sc25519_from64bytes(&schram, hram); + + sc25519_from32bytes(&scs, sm+32); + + ge25519_double_scalarmult_vartime(&get2, + &get1, + &schram, + &ge25519_base, + &scs); + ge25519_pack(t2, &get2); + + ret = crypto_verify_32(sm, t2); + if (ret != 0) { + for (i = 0; i < smlen - 64; i++) { + m[i] = sm[i + 64]; + } + *mlen = smlen-64; + } else { + for (i = 0; i < smlen - 64; i++) { + m[i] = 0; + } + } + + return ret; +} diff --git a/sxt/ppkp_ops.c b/sxt/ppkp_ops.c new file mode 100644 index 0000000..9844385 --- /dev/null +++ b/sxt/ppkp_ops.c @@ -0,0 +1,54 @@ +/* + * Secure eXtended Message Passing framework + * Secure eXtended Transport layer implementation: (libsxt) + * - very similar to SSH2/TLS + * - using already proven and tested crypto algos + * - better than TLS for message passing + * + * PublicPrivateKeyPairs operation API + * + * (c) Alexander Vdolainen 2016 + * + * libsxmp is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libsxmp is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see ."; + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#define EBADE 1 +#define NETDB_SUCCESS 0 +#else +#include +#include +#include +#include +#endif + +#include +#include +#include + +#include +