From eb7a8f7cfd290d925bfcf6904ca54081559b78d9 Mon Sep 17 00:00:00 2001 From: wipedlife Date: Tue, 22 Jun 2021 05:00:27 +0300 Subject: [PATCH] x25519 preinit --- libbacteria/encdec/async/x25519.c | 137 ++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 libbacteria/encdec/async/x25519.c diff --git a/libbacteria/encdec/async/x25519.c b/libbacteria/encdec/async/x25519.c new file mode 100644 index 0000000..727de4f --- /dev/null +++ b/libbacteria/encdec/async/x25519.c @@ -0,0 +1,137 @@ +#include +#include + +#include +#include + +#define LENKEY 32 +static size_t len_key = LENKEY; +struct keysPair{ + EVP_PKEY * privKey; //, *pubKey ; + unsigned char pubKey[LENKEY+1]; + EVP_PKEY_CTX * pKeyCtx;//just ctx +}; + + +struct keysPair createKeyPair(const uint8_t * priv, const uint8_t * pub){ + struct keysPair ret; + bzero(ret.pubKey,sizeof(ret.pubKey)); + EVP_PKEY_CTX * ctx = /*(EVP_CIPHER_CTX*)*/EVP_PKEY_CTX_new_id (NID_X25519, NULL); + if (!ctx){ + fprintf(stderr,"Cant create x25519 pair\n"); + return ret; + } + EVP_PKEY * privKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, len_key); + EVP_PKEY_get_raw_public_key(privKey, ret.pubKey, &len_key); + ret.privKey = privKey; + //ret.pubKey = pubKey; + ret.pKeyCtx=ctx; + return ret; +} + +void freeKeyPair(struct keysPair * pair){ + EVP_PKEY_CTX_free( pair->pKeyCtx ); + EVP_PKEY_free(pair->privKey); +// EVP_PKEY_free(pair->pubKey); +} +void freeSharedKeys(uint8_t * w, ...){ + va_list ap; + va_start(ap,w); + while(*w){ + OPENSSL_free(w); + } + va_end(ap); +} + +struct keysPair generateKeyPair(void){ + struct keysPair ret; + EVP_PKEY_CTX *ctx; + EVP_PKEY *pkey = NULL; + ctx = EVP_PKEY_CTX_new_id(NID_X25519, NULL); + if (!ctx){ + fprintf(stderr,"Cant create x25519 pair\n"); + return ret; + } + if (EVP_PKEY_keygen_init(ctx) <= 0){ + fprintf(stderr, "can't keygen x25519 pair\n"); + EVP_PKEY_CTX_free(ctx); + return ret; + } + EVP_PKEY_keygen (ctx, &pkey); + EVP_PKEY_CTX_free(ctx); + ctx = EVP_PKEY_CTX_new (pkey, NULL); + bzero(ret.pubKey,sizeof(ret.pubKey)); + EVP_PKEY_get_raw_public_key (pkey, ret.pubKey, &len_key); + //EVP_PKEY_CTX_free (ctx); + + ret.privKey=pkey; + //ret.pubKey=pubKey; + ret.pKeyCtx=ctx; + return ret; +} + +uint8_t * getSharedKey( struct keysPair * pair, const uint8_t * pubPeer, size_t * skeylen ){ + if (!pubPeer || (pubPeer[31] & 0x80)){ + fprintf(stderr,"Is not pubkey!\n"); + return NULL; + }// not x25519 key + + if(EVP_PKEY_derive_init(pair->pKeyCtx) <= 0){ + fprintf(stderr,"derive init error\n"); + return NULL; + } + + + EVP_PKEY * pkey = EVP_PKEY_new_raw_public_key (NID_X25519, NULL, pubPeer, len_key); + + if (EVP_PKEY_derive_set_peer(pair->pKeyCtx, pkey) <= 0) + { + fprintf(stderr,"Seet peer key error\n"); + EVP_PKEY_free (pkey); + return NULL; + } + if( EVP_PKEY_derive (pair->pKeyCtx, NULL, skeylen) <= 0){ + fprintf(stderr, "buffer length derive err\n"); + EVP_PKEY_free (pkey); + return NULL; + } + uint8_t * ret = OPENSSL_malloc(*skeylen); + if(ret == 0){ + fprintf(stderr,"OPENSSL malloc err\n"); + EVP_PKEY_free (pkey); + return NULL; + } + if( EVP_PKEY_derive (pair->pKeyCtx, ret, skeylen) <= 0){ + fprintf(stderr, "shared key write err\n"); + EVP_PKEY_free (pkey); + return NULL; + } + EVP_PKEY_free (pkey); + return ret; +} + +int test(void){ + struct keysPair pair = generateKeyPair(); + struct keysPair pair1 = generateKeyPair(); + if(pair.pKeyCtx == NULL || pair1.pKeyCtx == NULL ) { + return fprintf(stderr,"can't CTX init\n"); + } + printf("pubKey: %s\nLen(strlen): %d\n", pair.pubKey,strlen(pair.pubKey)); + printf("pubKey1: %s\nLen(strlen): %d\n", pair1.pubKey,strlen(pair1.pubKey)); + puts("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + size_t skeylen,skeylen1; + + //bzero(shared0,sizeof(shared0)); + //bzero(shared1,sizeof(shared0)); + uint8_t * shared0 = getSharedKey(&pair, pair1.pubKey,&skeylen); + uint8_t * shared1 = getSharedKey(&pair1, pair.pubKey, &skeylen1); + printf("shared0: %s \nshared1: %s \n",shared0,shared1); + freeSharedKeys(shared0,shared1,NULL); + freeKeyPair(&pair);freeKeyPair(&pair1); +} + +int main(void){ + puts("Start test"); + test(); + puts("Test is done"); +}