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

New files

Rev: src/arcfour.c:1.1
Rev: src/blowfish.c:1.1
Rev: src/cascade.c:1.1
Rev: src/cbc.c:1.1
Rev: src/des.c:1.1
Rev: src/hmac.c:1.1
Rev: src/md5.c:1.1
Rev: src/sha.c:1.1
parent 1f862443
/* arcfour.c
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "crypto.h"
#include "werror.h"
#include "xalloc.h"
#include "arcfour.h"
#include "arcfour.c.x"
/* CLASS:
(class
(name arcfour_instance)
(super crypto_instance)
(vars
(ctx simple "struct arcfour_ctx")))
*/
static void do_crypt_arcfour(struct crypto_instance *s,
UINT32 length, const UINT8 *src, UINT8 *dst)
{
CAST(arcfour_instance, self, s);
if (length % 8)
fatal("Internal error\n");
arcfour_crypt(&self->ctx, dst, src, length);
}
static struct crypto_instance *
make_arcfour_instance(struct crypto_algorithm *ignored UNUSED, int mode,
const UINT8 *key, const UINT8 *iv UNUSED)
{
NEW(arcfour_instance, self);
self->super.block_size = 8;
self->super.crypt = do_crypt_arcfour;
arcfour_set_key(&self->ctx, key, 16);
return &self->super;
}
struct crypto_algorithm crypto_arcfour_algorithm =
{ STATIC_HEADER,
8, 16, 0, make_arcfour_instance };
/* blowfish.c
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "crypto.h"
#include "werror.h"
#include "xalloc.h"
#include "blowfish.h"
#include <assert.h>
#include "blowfish.c.x"
/* Blowfish */
/* CLASS:
(class
(name blowfish_instance)
(super crypto_instance)
(vars
(ctx simple "BLOWFISH_context")))
*/
static void do_blowfish_encrypt(struct crypto_instance *s,
UINT32 length, const UINT8 *src, UINT8 *dst)
{
CAST(blowfish_instance, self, s);
FOR_BLOCKS(length, src, dst, BLOWFISH_BLOCKSIZE)
bf_encrypt_block(&self->ctx, dst, src);
}
static void do_blowfish_decrypt(struct crypto_instance *s,
UINT32 length, const UINT8 *src, UINT8 *dst)
{
CAST(blowfish_instance, self, s);
FOR_BLOCKS(length, src, dst, BLOWFISH_BLOCKSIZE)
bf_decrypt_block(&self->ctx, dst, src);
}
static struct crypto_instance *
make_blowfish_instance(struct crypto_algorithm *algorithm, int mode,
const UINT8 *key, const UINT8 *iv UNUSED)
{
NEW(blowfish_instance, self);
self->super.block_size = BLOWFISH_BLOCKSIZE;
self->super.crypt = ( (mode == CRYPTO_ENCRYPT)
? do_blowfish_encrypt
: do_blowfish_decrypt);
switch (bf_set_key(&self->ctx, key, algorithm->key_size))
{
case 0:
return &self->super;
default:
werror("Detected a weak blowfish key!\n");
KILL(self);
return NULL;
}
}
struct crypto_algorithm *make_blowfish_algorithm(UINT32 key_size)
{
NEW(crypto_algorithm, algorithm);
assert(key_size <= BLOWFISH_MAX_KEYSIZE);
assert(key_size >= BLOWFISH_MIN_KEYSIZE);
algorithm->block_size = BLOWFISH_BLOCKSIZE;
algorithm->key_size = key_size;
algorithm->iv_size = 0;
algorithm->make_crypt = make_blowfish_instance;
return algorithm;
}
struct crypto_algorithm *make_blowfish(void)
{
return make_blowfish_algorithm(BLOWFISH_KEYSIZE);
}
/* cascade.c
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "abstract_crypto.h"
#include "list.h"
#include "werror.h"
#include "xalloc.h"
#include <assert.h>
#include "cascade.c.x"
/* CLASS:
(class
(name crypto_cascade_algorithm)
(super crypto_algorithm)
(vars
(cascade object object_list)))
*/
/* CLASS:
(class
(name crypto_cascade_instance)
(super crypto_instance)
(vars
(cascade object object_list)))
*/
static void do_cascade_crypt(struct crypto_instance *s,
UINT32 length, const UINT8 *src, UINT8 *dst)
{
CAST(crypto_cascade_instance, self, s);
unsigned i;
if (length % self->super.block_size)
fatal("Internal error!\n");
assert(LIST_LENGTH(self->cascade));
{
CAST_SUBTYPE(crypto_instance, o, LIST(self->cascade)[0]);
CRYPT(o, length, src, dst);
}
for (i = 1; i<LIST_LENGTH(self->cascade); i++)
{
CAST_SUBTYPE(crypto_instance, o, LIST(self->cascade)[i]);
CRYPT(o, length, dst, dst);
}
}
static struct crypto_instance *
do_make_cascade(struct crypto_algorithm *s,
int mode, const UINT8 *key, const UINT8 *iv)
{
CAST(crypto_cascade_algorithm, algorithm, s);
NEW(crypto_cascade_instance, instance);
unsigned i;
instance->super.block_size = algorithm->super.block_size;
instance->cascade = alloc_object_list(LIST_LENGTH(algorithm->cascade));
for (i = 0; i<LIST_LENGTH(algorithm->cascade); i++)
{
/* When decrypting, the crypto algorithms should be used in
* reverse order! */
unsigned j = ( (mode == CRYPTO_ENCRYPT)
? i
: LIST_LENGTH(algorithm->cascade) - i - 1);
CAST_SUBTYPE(crypto_algorithm, a, LIST(algorithm->cascade)[j]);
struct crypto_instance *o = MAKE_CRYPT(a, mode, key, iv);
if (!o)
{
KILL(instance);
return NULL;
}
LIST(instance->cascade)[i] = (struct lsh_object *) o;
key += a->key_size;
iv += a->iv_size;
}
instance->super.crypt = do_cascade_crypt;
return &instance->super;
}
struct crypto_algorithm *crypto_cascadel(struct object_list *cascade)
{
NEW(crypto_cascade_algorithm, self);
unsigned i;
self->cascade = cascade;
self->super.key_size = self->super.iv_size = 0;
self->super.block_size = 1;
for (i = 0; i<LIST_LENGTH(self->cascade); i++)
{
CAST_SUBTYPE(crypto_algorithm, a, LIST(self->cascade)[i]);
self->super.key_size += a->key_size;
self->super.iv_size += a->iv_size;
self->super.block_size = lcm(self->super.block_size, a->block_size);
}
self->super.make_crypt = do_make_cascade;
return &self->super;
}
struct crypto_algorithm *crypto_cascade(unsigned n, ...)
{
va_list args;
struct object_list *l;
va_start(args, n);
l = make_object_listv(n, args);
va_end(args);
return crypto_cascadel(l);
}
/* cbc.c
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "crypto.h"
#include "werror.h"
#include "xalloc.h"
#include <assert.h>
#include "cbc.c.x"
/* CLASS:
(class
(name cbc_algorithm)
(super crypto_algorithm)
(vars
(inner object crypto_algorithm)))
*/
/* CLASS:
(class
(name cbc_instance)
(super crypto_instance)
(vars
(inner object crypto_instance)
(iv space UINT8)))
*/
static void do_cbc_encrypt(struct crypto_instance *s,
UINT32 length, const UINT8 *src, UINT8 *dst)
{
CAST(cbc_instance, self, s);
FOR_BLOCKS(length, src, dst, self->super.block_size)
{
memxor(self->iv, src, self->super.block_size);
CRYPT(self->inner, self->super.block_size, src, self->iv);
memcpy(dst, self->iv, self->super.block_size);
}
}
static void do_cbc_decrypt(struct crypto_instance *s,
UINT32 length, const UINT8 *src, UINT8 *dst)
{
CAST(cbc_instance, self, s);
if (length % self->super.block_size)
fatal("Internal error\n");
if (!length)
return;
/* Decrypt in ECB mode */
CRYPT(self->inner, length, src, dst);
/* XOR the cryptotext, shifted one block */
memxor(dst,
self->iv, self->super.block_size);
memxor(dst + self->super.block_size,
src, length - self->super.block_size);
memcpy(self->iv,
src + length - self->super.block_size, self->super.block_size);
}
static struct crypto_instance *
do_make_cbc_instance(struct crypto_algorithm *s,
int mode, const UINT8 *key, const UINT8 *iv)
{
CAST(cbc_algorithm, algorithm, s);
NEW(cbc_instance, instance);
instance->super.block_size = algorithm->super.block_size;
/* NOTE: We use a prefix of the iv, and pass the tail on to the
* inner block crypto. This allows nested chaining, although the
* semantics may be a little obscure.. */
instance->inner = MAKE_CRYPT(algorithm->inner, mode, key,
iv + algorithm->super.block_size);
if (!instance->inner)
{
/* Weak key */
KILL(instance);
return NULL;
}
instance->iv = lsh_space_alloc(algorithm->super.block_size);
memcpy(instance->iv, iv, algorithm->super.block_size);
instance->super.crypt = ( (mode == CRYPTO_ENCRYPT)
? do_cbc_encrypt
: do_cbc_decrypt);
return &instance->super;
}
struct crypto_algorithm *crypto_cbc(struct crypto_algorithm *inner)
{
NEW(cbc_algorithm, algorithm);
algorithm->super.block_size = inner->block_size;
algorithm->super.key_size = inner->key_size;
algorithm->super.iv_size = inner->iv_size + inner->block_size;
algorithm->inner = inner;
algorithm->super.make_crypt = do_make_cbc_instance;
return &algorithm->super;
}
/* des.c
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "crypto.h"
#include "werror.h"
#include "xalloc.h"
#include "des.h"
#include <assert.h>
#include "des.c.x"
/* CLASS:
(class
(name des_instance)
(super crypto_instance)
(vars
(ctx array (simple UINT32) DES_EXPANDED_KEYLEN)))
*/
static void do_des_encrypt(struct crypto_instance *s,
UINT32 length, const UINT8 *src, UINT8 *dst)
{
CAST(des_instance, self, s);
FOR_BLOCKS(length, src, dst, DES_BLOCKSIZE)
DesSmallFipsEncrypt(dst, self->ctx, src);
}
static void do_des_decrypt(struct crypto_instance *s,
UINT32 length, const UINT8 *src, UINT8 *dst)
{
CAST(des_instance, self, s);
FOR_BLOCKS(length, src, dst, DES_BLOCKSIZE)
DesSmallFipsDecrypt(dst, self->ctx, src);
}
static struct crypto_instance *
make_des_instance(struct crypto_algorithm *algorithm, int mode,
const UINT8 *key, const UINT8 *iv UNUSED)
{
NEW(des_instance, self);
UINT8 pkey[DES_KEYSIZE];
unsigned i;
/* Fix parity */
for (i=0; i<DES_KEYSIZE; i++)
{
UINT8 p = key[i];
p ^= (p >> 4);
p ^= (p >> 2);
p ^= (p >> 1);
pkey[i] = key[i] ^ (p & 1);
}
self->super.block_size = DES_BLOCKSIZE;
self->super.crypt = ( (mode == CRYPTO_ENCRYPT)
? do_des_encrypt
: do_des_decrypt);
switch (DesMethod(self->ctx, pkey))
{
case 0:
return &self->super;
case -1:
fatal("Internal error! Bad parity in make_des_instance.\n");
case -2:
werror("Detected weak DES key.\n");
KILL(self);
return NULL;
default:
fatal("Internal error!\n");
}
}
struct crypto_algorithm crypto_des_algorithm =
{ STATIC_HEADER,
DES_BLOCKSIZE, DES_KEYSIZE, 0, make_des_instance };
struct crypto_algorithm *make_des3(void)
{
return crypto_cascade(3,
&crypto_des_algorithm,
crypto_invert(&crypto_des_algorithm),
&crypto_des_algorithm,
-1);
}
/* hmac.c
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "crypto.h"
#include "xalloc.h"
#include <string.h>
#include "hmac.c.x"
/* The HMAC (rfc-2104) construction */
/* CLASS:
(class
(name hmac_algorithm)
(super mac_algorithm)
(vars
(hash object hash_algorithm)))
*/
/* CLASS:
(class
(name hmac_instance)
(super mac_instance)
(vars
; Initialized hash objects
(hinner object hash_instance)
(houter object hash_instance)
; Modified by update
(state object hash_instance)))
*/
static void do_hmac_update(struct mac_instance *s,
UINT32 length, UINT8 *data)
{
CAST(hmac_instance, self, s);
HASH_UPDATE(self->state, length, data);
}
static void do_hmac_digest(struct mac_instance *s,
UINT8 *data)
{
CAST(hmac_instance, self, s);
struct hash_instance *h = self->state;
HASH_DIGEST(h, data); /* Inner hash */
KILL(h);
h = HASH_COPY(self->houter);
HASH_UPDATE(h, self->super.mac_size, data);
HASH_DIGEST(h, data);
KILL(h);
self->state = HASH_COPY(self->hinner);
}
static struct mac_instance *do_hmac_copy(struct mac_instance *s)
{
CAST(hmac_instance, self, s);
CLONED(hmac_instance, new, self);
new->state = HASH_COPY(self->state);