|
|
|
/*
|
|
|
|
* 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 2.1 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)) break;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|