Commit 582674f0 authored by Niels Möller's avatar Niels Möller
Browse files

Integrated the crypto toolkit.

Rev: src/abstract_crypto.h:1.4
Rev: src/crypto.c:1.2
Rev: src/crypto.h:1.3
parent 7964631f
......@@ -17,18 +17,26 @@ struct crypto_instance
#define CRYPT(instance, length, src, dst) \
((instance)->crypt((instance), (length), (src), (dst)))
#define CRYPTO_ENCRYPT 0
#define CRYPTO_DECRYPT 1
struct crypto_algorithm
{
UINT32 block_size;
UINT32 key_size;
struct crypto_instance * (*make_encrypt)(struct crypto_algorithm *self,
UINT8 *key);
struct crypto_instance * (*make_decrypt)(struct crypto_algorithm *self,
UINT8 *key);
struct crypto_instance * (*make_crypt)(struct crypto_algorithm *self,
int mode,
UINT8 *key);
};
#define MAKE_ENCRYPT(crypto, key) \
((crypto)->make_crypt((crypto), CRYPTO_ENCRYPT, (key)))
#define MAKE_DECRYPT(crypto, key) \
((crypto)->make_crypt((crypto), CRYPTO_DECRYPT, (key)))
struct hash_instance
{
UINT32 hash_size;
......@@ -36,15 +44,17 @@ struct hash_instance
UINT32 length, UINT8 *data);
void (*digest)(struct hash_instance *self,
UINT8 *result);
struct hash_instance (*copy)(struct hash_instance *self);
struct hash_instance * (*copy)(struct hash_instance *self);
};
#define UPDATE(instance, length, data) \
#define HASH_UPDATE(instance, length, data) \
((instance)->update((instance), (length), (data)))
#define DIGEST(instance, result) \
#define HASH_DIGEST(instance, result) \
((instance)->digest((instance), (result)))
#define HASH_COPY(instance) ((instance)->copy((instance)))
/* Used for both hash functions ad macs */
#define mac_instance hash_instance
#define mac_size hash_size
......@@ -53,16 +63,26 @@ struct hash_algorithm
{
UINT32 block_size;
UINT32 hash_size;
struct hash_instance (*make_hash)(struct hash_algorithm *self);
struct hash_instance * (*make_hash)(struct hash_algorithm *self);
};
#define MAKE_HASH(h) ((h)->make_hash((h)))
struct mac_algorithm
{
UINT32 hash_size;
UINT32 key_size;
struct mac_instance (*make_mac)(struct mac_algorithm *self,
UINT8 *key);
struct mac_instance * (*make_mac)(struct mac_algorithm *self,
UINT8 *key);
};
#define MAKE_MAC(m, key) ((m)->make_mac((m), (key)))
struct randomness
{
void (*random)(struct randomness **closure, UINT32 length, UINT8 *dst);
};
#define RANDOM(r, length, dst) ((r)->random(&(r), length, dst))
#endif /* LSH_ABSTRACT_CRYPTO_H_INCLUDED */
......@@ -2,11 +2,21 @@
*
*/
#include <sys/types.h>
#include <time.h>
#include "crypto.h"
#include "sha.h"
#include "rc4.h"
#include "werror.h"
#include "xalloc.h"
/* No crypto */
static void do_crypt_none(struct crypto_instance *ignored,
UINT32 length, UINT8 *dst, UINT8 *src)
{
if (length % 8)
fatal("Internal error\n");
if (src != dst)
memcpy(dst, src, length);
}
......@@ -16,3 +26,249 @@ struct crypto_instance crypto_none_instance =
8,
do_crypt_none
};
struct rc4_instance
{
struct crypto_instance super;
struct rc4_ctx ctx;
};
static void do_crypt_rc4(struct crypto_instance *s,
UINT32 length, UINT8 *dst, UINT8 *src)
{
struct rc4_instance *self = (struct rc4_instance *) s;
if (length % 8)
fatal("Internal error\n");
rc4_crypt(&self->ctx, dst, src, length);
}
static struct crypto_instance *
make_rc4_instance(struct crypto_algorithm *ignored, int mode, UINT8 *key)
{
struct rc4_instance *self = xalloc(sizeof(struct rc4_instance));
self->super.block_size = 8;
self->super.crypt = do_crypt_rc4;
rc4_set_key(&self->ctx, key, 16);
return &self->super;
}
struct crypto_algorithm crypto_rc4_algorithm =
{ 8, 16, make_rc4_instance };
/* SHA1 hash */
struct sha_instance
{
struct hash_instance super;
struct sha_ctx ctx;
};
static void do_sha_update(struct hash_instance *s,
UINT32 length, UINT8 *data)
{
struct sha_instance *self = (struct sha_instance *) s;
sha_update(&self->ctx, data, length);
}
static void do_sha_digest(struct hash_instance *s,
UINT8 *dst)
{
struct sha_instance *self = (struct sha_instance *) s;
sha_final(&self->ctx);
sha_digest(&self->ctx, dst);
sha_init(&self->ctx);
}
static struct hash_instance *do_sha_copy(struct hash_instance *s)
{
struct sha_instance *self = (struct sha_instance *) s;
struct sha_instance *new = xalloc(sizeof(struct sha_instance));
memcpy(new, self, sizeof(*self));
return &new->super;
}
static struct hash_instance *make_sha_instance(struct hash_algorithm *ignored)
{
struct sha_instance *res = xalloc(sizeof(struct sha_instance));
res->super.hash_size = 20;
res->super.update = do_sha_update;
res->super.digest = do_sha_digest;
res->super.copy = do_sha_copy;
sha_init(&res->ctx);
return &res->super;
}
struct hash_algorithm sha_algorithm =
{ 64, 20, make_sha_instance };
/* HMAC */
struct hmac_algorithm
{
struct mac_algorithm super;
struct hash_algorithm *hash;
};
struct hmac_instance
{
struct mac_instance super;
/* Initialized hash objects */
struct hash_instance *hinner;
struct hash_instance *houter;
/* Modified by update */
struct hash_instance *state;
};
static void do_hmac_update(struct mac_instance *s,
UINT32 length, UINT8 *data)
{
struct hmac_instance *self = (struct hmac_instance *) s;
HASH_UPDATE(self->state, length, data);
}
static void do_hmac_digest(struct mac_instance *s,
UINT8 *data)
{
struct hmac_instance *self = (struct hmac_instance *) s;
struct hash_instance *h = self->state;
HASH_DIGEST(h, data); /* Inner hash */
lsh_free(h);
h = HASH_COPY(self->houter);
HASH_UPDATE(h, self->super.mac_size, data);
HASH_DIGEST(h, data);
lsh_free(h);
self->state = HASH_COPY(self->hinner);
}
static struct mac_instance *do_hmac_copy(struct mac_instance *s)
{
struct hmac_instance *self = (struct hmac_instance *) s;
struct hmac_instance *new = xalloc(sizeof(struct hmac_instance));
memcpy(&new->super, &self->super, sizeof(self->super));
/* FIXME: Sharing hinner and houter objects makes gc more difficult */
new->hinner = self->hinner;
new->houter = self->houter;
new->state = HASH_COPY(self->state);
return &new->super;
}
#define IPAD 0x36
#define OPAD 0x5c
static struct mac_instance *make_hmac_instance(struct mac_algorithm *s,
UINT8 *key)
{
struct hmac_algorithm *self = (struct hmac_algorithm *) s;
struct hmac_instance *instance = xalloc(sizeof(struct hmac_instance));
UINT8 *pad = alloca(self->hash->block_size);
int i;
instance->super.hash_size = self->super.hash_size;
instance->super.update = do_hmac_update;
instance->super.digest = do_hmac_digest;
instance->super.copy = do_hmac_copy;
instance->hinner = MAKE_HASH(self->hash);
memset(pad, IPAD, self->hash->block_size);
for(i = 0; i<self->hash->hash_size; i++)
pad[i] ^= key[i];
HASH_UPDATE(instance->hinner, self->hash->block_size, pad);
instance->houter = MAKE_HASH(self->hash);
memset(pad, OPAD, self->hash->block_size);
for(i = 0; i<self->hash->hash_size; i++)
pad[i] ^= key[i];
HASH_UPDATE(instance->houter, self->hash->block_size, pad);
instance->state = HASH_COPY(instance->hinner);
return &instance->super;
}
struct mac_algorithm *make_hmac_algorithm(struct hash_algorithm *h)
{
struct hmac_algorithm *self = xalloc(sizeof(struct hmac_algorithm));
self->super.hash_size = h->hash_size;
/* Recommended in RFC-2104 */
self->super.key_size = h->hash_size;
self->super.make_mac = make_hmac_instance;
self->hash = h;
return &self->super;
}
/* Random */
struct poor_random
{
struct randomness super;
struct hash_instance *hash;
UINT32 pos;
UINT8 buffer[1];
};
static void do_poor_random(struct randomness **r, UINT32 length, UINT8 *dst)
{
struct poor_random *self = (struct poor_random *) *r;
while(length)
{
UINT32 available = self->hash->hash_size - self->pos;
UINT32 to_copy;
if (!available)
{
time_t now = time(NULL); /* To avoid cycles */
HASH_UPDATE(self->hash, sizeof(now), (UINT8 *) &now);
HASH_UPDATE(self->hash, self->hash->hash_size,
self->buffer);
HASH_DIGEST(self->hash, self->buffer);
available = self->hash->hash_size;
self->pos = 0;
}
to_copy = MIN(available, length);
memcpy(dst, self->buffer + self->pos, to_copy);
length -= to_copy;
dst += to_copy;
self->pos += to_copy;
}
}
struct randomness *make_poor_random(struct hash_algorithm *hash,
struct lsh_string *init)
{
struct poor_random *self
= xalloc(sizeof(struct poor_random) - 1 + hash->hash_size);
time_t now = time(NULL); /* To avoid cycles */
self->super.random = do_poor_random;
self->hash = MAKE_HASH(hash);
HASH_UPDATE(self->hash, sizeof(now), (UINT8 *) &now);
HASH_UPDATE(self->hash, init->length, init->data);
HASH_DIGEST(self->hash, self->buffer);
self->pos = 0;
return &self->super;
}
......@@ -8,5 +8,13 @@
#include "abstract_crypto.h"
extern struct crypto_instance crypto_none_instance;
extern struct crypto_algorithm crypto_rc4_algorithm;
extern struct hash_algorithm sha_algorithm;
struct mac_algorithm *make_hmac_algorithm(struct hash_algorithm *h);
struct randomness *make_poor_random(struct hash_algorithm *hash,
struct lsh_string *init);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment