sxt: added ciphers stubs, wrappers and API impl.;
parent
d760958018
commit
1e64efb4c0
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Ciphers API
|
||||
*
|
||||
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.";
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sxt/errno.h>
|
||||
#include <sxt/ciphers.h>
|
||||
#include <sxt/lcrypt.h>
|
||||
|
||||
#include <tdata/list.h>
|
||||
|
||||
static list_head_t cipher_listhead;
|
||||
static int __list_initied = 0;
|
||||
|
||||
struct cipher_tbl {
|
||||
sxt_cipher_t *cipher;
|
||||
list_node_t node;
|
||||
};
|
||||
|
||||
static sxt_cipher_t *__alloc_cipher(const char *name, unsigned int blksize,
|
||||
unsigned int keylen, struct _cipher_ops *f)
|
||||
{
|
||||
sxt_cipher_t *n = NULL;
|
||||
|
||||
if(!name || !f) return NULL;
|
||||
|
||||
if(!(n = malloc(sizeof(sxt_cipher_t)))) return NULL;
|
||||
if(!(n->name = strdup(name))) {
|
||||
free(n);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n->blksize = blksize;
|
||||
n->keylen = keylen;
|
||||
n->f = f;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* API for workout with table */
|
||||
sxt_cipher_t *sxt_cipher_get(const char *name)
|
||||
{
|
||||
sxt_cipher_t *sc = NULL, *nn = NULL;
|
||||
struct cipher_tbl *entry = NULL;
|
||||
list_node_t *iter, *siter;
|
||||
|
||||
if(!__list_initied || !name) return NULL;
|
||||
|
||||
list_for_each_safe(&cipher_listhead, iter, siter) {
|
||||
entry = list_entry(iter, struct cipher_tbl, node);
|
||||
sc = entry->cipher;
|
||||
if(!strcmp(sxt_cipher_getname(sc), name)) return sc;
|
||||
else sc = NULL;
|
||||
}
|
||||
|
||||
if(sc) {
|
||||
nn = malloc(sizeof(sxt_cipher_t));
|
||||
if(!nn) return NULL;
|
||||
else memset(nn, 0, sizeof(sxt_cipher_t));
|
||||
nn->name = sc->name;
|
||||
nn->f = sc->f;
|
||||
nn->blksize = sc->blksize;
|
||||
nn->keylen = sc->keylen;
|
||||
nn->keysize = sc->keysize;
|
||||
if(lcrypt_alloc_keystub(nn)) {
|
||||
free(nn);
|
||||
nn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return nn;
|
||||
}
|
||||
|
||||
void sxt_cipher_free(sxt_cipher_t *c)
|
||||
{
|
||||
if(!c) return;
|
||||
|
||||
lcrypt_cleanup_keystub(c);
|
||||
memset(c, 0, sizeof(sxt_cipher_t));
|
||||
free(c);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int sxt_cipher_add(const char *name, unsigned int blksize, unsigned int keylen,
|
||||
unsigned int keysz, struct _cipher_ops *f)
|
||||
{
|
||||
struct cipher_tbl *ne = NULL;
|
||||
sxt_cipher_t *nec = NULL;
|
||||
|
||||
/* take a check for head first */
|
||||
if(!__list_initied) {
|
||||
list_init_head(&cipher_listhead);
|
||||
__list_initied = 1;
|
||||
}
|
||||
|
||||
if(!f) return SXT_EINVAL;
|
||||
if(!(ne = malloc(sizeof(struct cipher_tbl)))) return SXT_ENOMEM;
|
||||
else {
|
||||
nec = __alloc_cipher(name, blksize, keylen, f);
|
||||
if(!nec) {
|
||||
free(ne);
|
||||
return SXT_ENOMEM;
|
||||
} else nec->keysize = keysz;
|
||||
|
||||
ne->cipher = nec;
|
||||
list_init_node(&ne->node);
|
||||
list_add2tail(&cipher_listhead, &ne->node);
|
||||
}
|
||||
|
||||
return SXT_SUCCESS;
|
||||
}
|
||||
|
||||
/* API to deal with cipher */
|
||||
const char *sxt_cipher_getname(sxt_cipher_t *c)
|
||||
{
|
||||
if(!c || !c->name) return "none";
|
||||
else return c->name;
|
||||
}
|
||||
|
||||
int sxt_cipher_set_encrypt_key(sxt_cipher_t *c, void *key, void *ivec)
|
||||
{
|
||||
if(!c || !key) return SXT_EINVAL;
|
||||
if(!ivec) return SXT_EINVAL;
|
||||
|
||||
return c->f->set_encrypt_key(c, key, ivec);
|
||||
}
|
||||
|
||||
int sxt_cipher_set_decrypt_key(sxt_cipher_t *c, void *key, void *ivec)
|
||||
{
|
||||
if(!c || !key) return SXT_EINVAL;
|
||||
if(!ivec) return SXT_EINVAL;
|
||||
|
||||
return c->f->set_decrypt_key(c, key, ivec);
|
||||
}
|
||||
|
||||
void sxt_cipher_encrypt(sxt_cipher_t *c, void *in, void *out, unsigned long size)
|
||||
{
|
||||
if(!c || !size) return;
|
||||
if(!in || !out) return;
|
||||
|
||||
c->f->encrypt(c, in, out, size);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void sxt_cipher_decrypt(sxt_cipher_t *c, void *in, void *out, unsigned long size)
|
||||
{
|
||||
if(!c || !size) return;
|
||||
if(!in || !out) return;
|
||||
|
||||
c->f->decrypt(c, in, out, size);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* libressl/openssl wrappers
|
||||
*
|
||||
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.";
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/blowfish.h>
|
||||
|
||||
#include <sxt/errno.h>
|
||||
#include <sxt/ciphers.h>
|
||||
#include <sxt/lcrypt.h>
|
||||
|
||||
/* internals */
|
||||
static int __alloc_keybuf(sxt_cipher_t *c)
|
||||
{
|
||||
if(!c->lcp) return -1;
|
||||
if(!(c->lcp->key = malloc(c->keylen))) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lcrypt_cleanup_keystub(sxt_cipher_t *c)
|
||||
{
|
||||
if(!c || !c->lcp) return;
|
||||
|
||||
memset(c->lcp->key, 0, sizeof(c->keylen));
|
||||
free(c->lcp->key);
|
||||
|
||||
memset(c->lcp, 0, sizeof(struct _lcrypt_cipher_priv));
|
||||
free(c->lcp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int lcrypt_alloc_keystub(sxt_cipher_t *c)
|
||||
{
|
||||
if(!c) return -1;
|
||||
|
||||
if(!(c->lcp = malloc(sizeof(struct _lcrypt_cipher_priv)))) return -1;
|
||||
else memset(c->lcp, 0, sizeof(struct _lcrypt_cipher_priv));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* AES */
|
||||
static int aes_set_encrypt_key(sxt_cipher_t *cipher, void *key, void *ivec)
|
||||
{
|
||||
if (cipher->lcp->key == NULL) {
|
||||
if (__alloc_keybuf(cipher) < 0) return -1;
|
||||
|
||||
if(AES_set_encrypt_key(key, cipher->keysize, cipher->lcp->key) < 0) {
|
||||
if(cipher->lcp->key) {
|
||||
memset(cipher->lcp->key, 0, cipher->keylen);
|
||||
free(cipher->lcp->key);
|
||||
cipher->lcp->key = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
cipher->lcp->ivec = ivec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aes_set_decrypt_key(sxt_cipher_t *cipher, void *key, void *ivec)
|
||||
{
|
||||
if (cipher->lcp->key == NULL) {
|
||||
if (__alloc_keybuf(cipher) < 0) return -1;
|
||||
|
||||
if (AES_set_decrypt_key(key, cipher->keysize, cipher->lcp->key) < 0) {
|
||||
if(cipher->lcp->key) {
|
||||
memset(cipher->lcp->key, 0, cipher->keylen);
|
||||
free(cipher->lcp->key);
|
||||
cipher->lcp->key = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
cipher->lcp->ivec = ivec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aes_encrypt(sxt_cipher_t *cipher, void *in, void *out,
|
||||
unsigned long len)
|
||||
{
|
||||
AES_cbc_encrypt(in, out, len, cipher->lcp->key, cipher->lcp->ivec, AES_ENCRYPT);
|
||||
}
|
||||
|
||||
static void aes_decrypt(sxt_cipher_t *cipher, void *in, void *out,
|
||||
unsigned long len)
|
||||
{
|
||||
AES_cbc_encrypt(in, out, len, cipher->lcp->key, cipher->lcp->ivec, AES_DECRYPT);
|
||||
}
|
||||
|
||||
static struct _cipher_ops aes_ops = {
|
||||
.set_encrypt_key = aes_set_encrypt_key,
|
||||
.set_decrypt_key = aes_set_decrypt_key,
|
||||
.encrypt = aes_encrypt,
|
||||
.decrypt = aes_decrypt,
|
||||
};
|
||||
|
||||
/* blow fish */
|
||||
static int blowfish_set_key(sxt_cipher_t *cipher, void *key, void *ivec)
|
||||
{
|
||||
if (cipher->lcp->key == NULL) {
|
||||
if (__alloc_keybuf(cipher) < 0) return -1;
|
||||
|
||||
BF_set_key(cipher->lcp->key, 16, key);
|
||||
}
|
||||
cipher->lcp->ivec = ivec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void blowfish_encrypt(sxt_cipher_t *cipher, void *in,
|
||||
void *out, unsigned long len)
|
||||
{
|
||||
BF_cbc_encrypt(in, out, len, cipher->lcp->key, cipher->lcp->ivec, BF_ENCRYPT);
|
||||
}
|
||||
|
||||
static void blowfish_decrypt(sxt_cipher_t *cipher, void *in,
|
||||
void *out, unsigned long len)
|
||||
{
|
||||
BF_cbc_encrypt(in, out, len, cipher->lcp->key, cipher->lcp->ivec, BF_DECRYPT);
|
||||
}
|
||||
|
||||
static struct _cipher_ops bf_ops = {
|
||||
.set_encrypt_key = blowfish_set_key,
|
||||
.set_decrypt_key = blowfish_set_key,
|
||||
.encrypt = blowfish_encrypt,
|
||||
.decrypt = blowfish_decrypt,
|
||||
};
|
||||
|
||||
int lcrypt_init_ciphers(void)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
r = sxt_cipher_add("blowfish-cbc", 8, sizeof(BF_KEY), 128, &bf_ops);
|
||||
r = sxt_cipher_add("aes128-cbc", 16, sizeof(AES_KEY), 128, &aes_ops);
|
||||
r = sxt_cipher_add("aes192-cbc", 16, sizeof(AES_KEY), 192, &aes_ops);
|
||||
r = sxt_cipher_add("aes256-cbc", 16, sizeof(AES_KEY), 256, &aes_ops);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
Loading…
Reference in New Issue