Blame src/cipher.c

Packit Service 37472d
Packit Service 37472d
/*
Packit Service 37472d
  Meanwhile - Unofficial Lotus Sametime Community Client Library
Packit Service 37472d
  Copyright (C) 2004  Christopher (siege) O'Brien
Packit Service 37472d
  
Packit Service 37472d
  This library is free software; you can redistribute it and/or
Packit Service 37472d
  modify it under the terms of the GNU Library General Public
Packit Service 37472d
  License as published by the Free Software Foundation; either
Packit Service 37472d
  version 2 of the License, or (at your option) any later version.
Packit Service 37472d
  
Packit Service 37472d
  This library is distributed in the hope that it will be useful,
Packit Service 37472d
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 37472d
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 37472d
  Library General Public License for more details.
Packit Service 37472d
  
Packit Service 37472d
  You should have received a copy of the GNU Library General Public
Packit Service 37472d
  License along with this library; if not, write to the Free
Packit Service 37472d
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit Service 37472d
*/
Packit Service 37472d
Packit Service 37472d
#include <stdlib.h>
Packit Service 37472d
#include <time.h>
Packit Service 37472d
Packit Service 37472d
#include "mpi/mpi.h"
Packit Service 37472d
Packit Service 37472d
#include "mw_channel.h"
Packit Service 37472d
#include "mw_cipher.h"
Packit Service 37472d
#include "mw_debug.h"
Packit Service 37472d
#include "mw_session.h"
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwMpi {
Packit Service 37472d
  mw_mp_int i;
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** From RFC2268 */
Packit Service 37472d
static guchar PT[] = {
Packit Service 37472d
  0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
Packit Service 37472d
  0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
Packit Service 37472d
  0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
Packit Service 37472d
  0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
Packit Service 37472d
  0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
Packit Service 37472d
  0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
Packit Service 37472d
  0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
Packit Service 37472d
  0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
Packit Service 37472d
  0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
Packit Service 37472d
  0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
Packit Service 37472d
  0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
Packit Service 37472d
  0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
Packit Service 37472d
  0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
Packit Service 37472d
  0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
Packit Service 37472d
  0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
Packit Service 37472d
  0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
Packit Service 37472d
  0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
Packit Service 37472d
  0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
Packit Service 37472d
  0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
Packit Service 37472d
  0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
Packit Service 37472d
  0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
Packit Service 37472d
  0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
Packit Service 37472d
  0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
Packit Service 37472d
  0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
Packit Service 37472d
  0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
Packit Service 37472d
  0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
Packit Service 37472d
  0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
Packit Service 37472d
  0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
Packit Service 37472d
  0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
Packit Service 37472d
  0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
Packit Service 37472d
  0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
Packit Service 37472d
  0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** prime number used in DH exchange */
Packit Service 37472d
static guchar dh_prime[] = {
Packit Service 37472d
  0xCF, 0x84, 0xAF, 0xCE, 0x86, 0xDD, 0xFA, 0x52,
Packit Service 37472d
  0x7F, 0x13, 0x6D, 0x10, 0x35, 0x75, 0x28, 0xEE,
Packit Service 37472d
  0xFB, 0xA0, 0xAF, 0xEF, 0x80, 0x8F, 0x29, 0x17,
Packit Service 37472d
  0x4E, 0x3B, 0x6A, 0x9E, 0x97, 0x00, 0x01, 0x71,
Packit Service 37472d
  0x7C, 0x8F, 0x10, 0x6C, 0x41, 0xC1, 0x61, 0xA6,
Packit Service 37472d
  0xCE, 0x91, 0x05, 0x7B, 0x34, 0xDA, 0x62, 0xCB,
Packit Service 37472d
  0xB8, 0x7B, 0xFD, 0xC1, 0xB3, 0x5C, 0x1B, 0x91,
Packit Service 37472d
  0x0F, 0xEA, 0x72, 0x24, 0x9D, 0x56, 0x6B, 0x9F
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** base used in DH exchange */
Packit Service 37472d
#define DH_BASE  3
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwMpi *mwMpi_new() {
Packit Service 37472d
  struct mwMpi *i;
Packit Service 37472d
  i = g_new0(struct mwMpi, 1);
Packit Service 37472d
  mw_mp_init(&i->i);
Packit Service 37472d
  return i;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwMpi_free(struct mwMpi *i) {
Packit Service 37472d
  if(! i) return;
Packit Service 37472d
  mw_mp_clear(&i->i);
Packit Service 37472d
  g_free(i);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void mwInitDHPrime(mw_mp_int *i) {
Packit Service 37472d
  mw_mp_init(i);
Packit Service 37472d
  mw_mp_read_unsigned_bin(i, dh_prime, 64);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwMpi_setDHPrime(struct mwMpi *i) {
Packit Service 37472d
  g_return_if_fail(i != NULL);
Packit Service 37472d
  mw_mp_read_unsigned_bin(&i->i, dh_prime, 64);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void mwInitDHBase(mw_mp_int *i) {
Packit Service 37472d
  mw_mp_init(i);
Packit Service 37472d
  mw_mp_set_int(i, DH_BASE);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwMpi_setDHBase(struct mwMpi *i) {
Packit Service 37472d
  g_return_if_fail(i != NULL);
Packit Service 37472d
  mw_mp_set_int(&i->i, DH_BASE);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void mw_mp_set_rand(mw_mp_int *i, guint bits) {
Packit Service 37472d
  size_t len, l;
Packit Service 37472d
  guchar *buf;
Packit Service 37472d
Packit Service 37472d
  l = len = (bits / 8) + 1;
Packit Service 37472d
  buf = g_malloc(len);
Packit Service 37472d
Packit Service 37472d
  srand(time(NULL));
Packit Service 37472d
  while(l--) buf[l] = rand() & 0xff;
Packit Service 37472d
Packit Service 37472d
  buf[0] &= (0xff >> (8 - (bits % 8)));
Packit Service 37472d
Packit Service 37472d
  mw_mp_read_unsigned_bin(i, buf, len);
Packit Service 37472d
  g_free(buf);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void mwDHRandKeypair(mw_mp_int *private_key, mw_mp_int *public_key) {
Packit Service 37472d
  mw_mp_int prime, base;
Packit Service 37472d
 
Packit Service 37472d
  mwInitDHPrime(&prime);
Packit Service 37472d
  mwInitDHBase(&base);
Packit Service 37472d
Packit Service 37472d
  mw_mp_set_rand(private_key, 512);
Packit Service 37472d
  mw_mp_exptmod(&base, private_key, &prime, public_key);
Packit Service 37472d
Packit Service 37472d
  mw_mp_clear(&prime);
Packit Service 37472d
  mw_mp_clear(&base);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwMpi_randDHKeypair(struct mwMpi *private_key, struct mwMpi *public_key) {
Packit Service 37472d
  g_return_if_fail(private_key != NULL);
Packit Service 37472d
  g_return_if_fail(public_key != NULL);
Packit Service 37472d
Packit Service 37472d
  mwDHRandKeypair(&private_key->i, &public_key->i);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void mwDHCalculateShared(mw_mp_int *shared_key, mw_mp_int *remote_key,
Packit Service 37472d
				mw_mp_int *private_key) {
Packit Service 37472d
  mw_mp_int prime;
Packit Service 37472d
 
Packit Service 37472d
  mwInitDHPrime(&prime);
Packit Service 37472d
  mw_mp_exptmod(remote_key, private_key, &prime, shared_key);
Packit Service 37472d
  mw_mp_clear(&prime);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwMpi_calculateDHShared(struct mwMpi *shared_key, struct mwMpi *remote_key,
Packit Service 37472d
			     struct mwMpi *private_key) {
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(shared_key != NULL);
Packit Service 37472d
  g_return_if_fail(remote_key != NULL);
Packit Service 37472d
  g_return_if_fail(private_key != NULL);
Packit Service 37472d
Packit Service 37472d
  mwDHCalculateShared(&shared_key->i, &remote_key->i, &private_key->i);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void mwDHImportKey(mw_mp_int *key, struct mwOpaque *o) {
Packit Service 37472d
  mw_mp_read_unsigned_bin(key, o->data, o->len);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwMpi_import(struct mwMpi *i, struct mwOpaque *o) {
Packit Service 37472d
  g_return_if_fail(i != NULL);
Packit Service 37472d
  g_return_if_fail(o != NULL);
Packit Service 37472d
Packit Service 37472d
  mwDHImportKey(&i->i, o);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void mwDHExportKey(mw_mp_int *key, struct mwOpaque *o) {
Packit Service 37472d
  o->len = mw_mp_unsigned_bin_size(key);
Packit Service 37472d
  o->data = g_malloc0(o->len);
Packit Service 37472d
  mw_mp_to_unsigned_bin(key, o->data);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwMpi_export(struct mwMpi *i, struct mwOpaque *o) {
Packit Service 37472d
  g_return_if_fail(i != NULL);
Packit Service 37472d
  g_return_if_fail(o != NULL);
Packit Service 37472d
  
Packit Service 37472d
  mwDHExportKey(&i->i, o);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwKeyRandom(guchar *key, gsize keylen) {
Packit Service 37472d
  g_return_if_fail(key != NULL);
Packit Service 37472d
Packit Service 37472d
  srand(time(NULL));
Packit Service 37472d
  while(keylen--) key[keylen] = rand() & 0xff;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwIV_init(guchar *iv) {
Packit Service 37472d
  iv[0] = 0x01;
Packit Service 37472d
  iv[1] = 0x23;
Packit Service 37472d
  iv[2] = 0x45;
Packit Service 37472d
  iv[3] = 0x67;
Packit Service 37472d
  iv[4] = 0x89;
Packit Service 37472d
  iv[5] = 0xab;
Packit Service 37472d
  iv[6] = 0xcd;
Packit Service 37472d
  iv[7] = 0xef;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/* This does not seem to produce the same results as normal RC2 key
Packit Service 37472d
   expansion would, but it works, so eh. It might be smart to farm
Packit Service 37472d
   this out to mozilla or openssl */
Packit Service 37472d
void mwKeyExpand(int *ekey, const guchar *key, gsize keylen) {
Packit Service 37472d
  guchar tmp[128];
Packit Service 37472d
  int i, j;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(keylen > 0);
Packit Service 37472d
  g_return_if_fail(key != NULL);
Packit Service 37472d
Packit Service 37472d
  if(keylen > 128) keylen = 128;
Packit Service 37472d
Packit Service 37472d
  /* fill the first chunk with what key bytes we have */
Packit Service 37472d
  for(i = keylen; i--; tmp[i] = key[i]);
Packit Service 37472d
  /* memcpy(tmp, key, keylen); */
Packit Service 37472d
Packit Service 37472d
  /* build the remaining key from the given data */
Packit Service 37472d
  for(i = 0; keylen < 128; i++) {
Packit Service 37472d
    tmp[keylen] = PT[ (tmp[keylen - 1] + tmp[i]) & 0xff ];
Packit Service 37472d
    keylen++;
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  tmp[0] = PT[ tmp[0] & 0xff ];
Packit Service 37472d
Packit Service 37472d
  for(i = 0, j = 0; i < 64; i++) {
Packit Service 37472d
    ekey[i] = (tmp[j] & 0xff) | (tmp[j+1] << 8);
Packit Service 37472d
    j += 2;
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/* normal RC2 encryption given a full 128-byte (as 64 ints) key */
Packit Service 37472d
static void mwEncryptBlock(const int *ekey, guchar *out) {
Packit Service 37472d
Packit Service 37472d
  int a, b, c, d;
Packit Service 37472d
  int i, j;
Packit Service 37472d
Packit Service 37472d
  a = (out[7] << 8) | (out[6] & 0xff);
Packit Service 37472d
  b = (out[5] << 8) | (out[4] & 0xff);
Packit Service 37472d
  c = (out[3] << 8) | (out[2] & 0xff);
Packit Service 37472d
  d = (out[1] << 8) | (out[0] & 0xff);
Packit Service 37472d
Packit Service 37472d
  for(i = 0; i < 16; i++) {
Packit Service 37472d
    j = i * 4;
Packit Service 37472d
Packit Service 37472d
    d += ((c & (a ^ 0xffff)) + (b & a) + ekey[j++]);
Packit Service 37472d
    d = (d << 1) | (d >> 15 & 0x0001);
Packit Service 37472d
Packit Service 37472d
    c += ((b & (d ^ 0xffff)) + (a & d) + ekey[j++]);
Packit Service 37472d
    c = (c << 2) | (c >> 14 & 0x0003);
Packit Service 37472d
Packit Service 37472d
    b += ((a & (c ^ 0xffff)) + (d & c) + ekey[j++]);
Packit Service 37472d
    b = (b << 3) | (b >> 13 & 0x0007);
Packit Service 37472d
    
Packit Service 37472d
    a += ((d & (b ^ 0xffff)) + (c & b) + ekey[j++]);
Packit Service 37472d
    a = (a << 5) | (a >> 11 & 0x001f);
Packit Service 37472d
Packit Service 37472d
    if(i == 4 || i == 10) {
Packit Service 37472d
      d += ekey[a & 0x003f];
Packit Service 37472d
      c += ekey[d & 0x003f];
Packit Service 37472d
      b += ekey[c & 0x003f];
Packit Service 37472d
      a += ekey[b & 0x003f];
Packit Service 37472d
    }    
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  *out++ = d & 0xff;
Packit Service 37472d
  *out++ = (d >> 8) & 0xff;
Packit Service 37472d
  *out++ = c & 0xff;
Packit Service 37472d
  *out++ = (c >> 8) & 0xff;
Packit Service 37472d
  *out++ = b & 0xff;
Packit Service 37472d
  *out++ = (b >> 8) & 0xff;
Packit Service 37472d
  *out++ = a & 0xff;
Packit Service 37472d
  *out++ = (a >> 8) & 0xff;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwEncryptExpanded(const int *ekey, guchar *iv,
Packit Service 37472d
		       struct mwOpaque *in_data,
Packit Service 37472d
		       struct mwOpaque *out_data) {
Packit Service 37472d
Packit Service 37472d
  guchar *i = in_data->data;
Packit Service 37472d
  gsize i_len = in_data->len;
Packit Service 37472d
Packit Service 37472d
  guchar *o;
Packit Service 37472d
  gsize o_len;
Packit Service 37472d
Packit Service 37472d
  int x, y;
Packit Service 37472d
Packit Service 37472d
  /* pad upwards to a multiple of 8 */
Packit Service 37472d
  /* o_len = (i_len & -8) + 8; */
Packit Service 37472d
  o_len = i_len + (8 - (i_len % 8));
Packit Service 37472d
  o = g_malloc(o_len);
Packit Service 37472d
Packit Service 37472d
  out_data->data = o;
Packit Service 37472d
  out_data->len = o_len;
Packit Service 37472d
Packit Service 37472d
  /* figure out the amount of padding */
Packit Service 37472d
  y = o_len - i_len;
Packit Service 37472d
Packit Service 37472d
  /* copy in to out, and write padding bytes */
Packit Service 37472d
  for(x = i_len; x--; o[x] = i[x]);
Packit Service 37472d
  for(x = i_len; x < o_len; o[x++] = y);
Packit Service 37472d
  /* memcpy(o, i, i_len);
Packit Service 37472d
     memset(o + i_len, y, y); */
Packit Service 37472d
Packit Service 37472d
  /* encrypt in blocks */
Packit Service 37472d
  for(x = o_len; x > 0; x -= 8) {
Packit Service 37472d
    for(y = 8; y--; o[y] ^= iv[y]);
Packit Service 37472d
    mwEncryptBlock(ekey, o);
Packit Service 37472d
    for(y = 8; y--; iv[y] = o[y]);
Packit Service 37472d
    /* memcpy(iv, o, 8); */
Packit Service 37472d
    o += 8;
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwEncrypt(const guchar *key, gsize keylen, guchar *iv,
Packit Service 37472d
	       struct mwOpaque *in, struct mwOpaque *out) {
Packit Service 37472d
Packit Service 37472d
  int ekey[64];
Packit Service 37472d
  mwKeyExpand(ekey, key, keylen);
Packit Service 37472d
  mwEncryptExpanded(ekey, iv, in, out);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void mwDecryptBlock(const int *ekey, guchar *out) {
Packit Service 37472d
Packit Service 37472d
  int a, b, c, d;
Packit Service 37472d
  int i, j;
Packit Service 37472d
Packit Service 37472d
  a = (out[7] << 8) | (out[6] & 0xff);
Packit Service 37472d
  b = (out[5] << 8) | (out[4] & 0xff);
Packit Service 37472d
  c = (out[3] << 8) | (out[2] & 0xff);
Packit Service 37472d
  d = (out[1] << 8) | (out[0] & 0xff);
Packit Service 37472d
Packit Service 37472d
  for(i = 16; i--; ) {
Packit Service 37472d
    j = i * 4 + 3;
Packit Service 37472d
Packit Service 37472d
    a = (a << 11) | (a >> 5 & 0x07ff);
Packit Service 37472d
    a -= ((d & (b ^ 0xffff)) + (c & b) + ekey[j--]);
Packit Service 37472d
Packit Service 37472d
    b = (b << 13) | (b >> 3 & 0x1fff);
Packit Service 37472d
    b -= ((a & (c ^ 0xffff)) + (d & c) + ekey[j--]);
Packit Service 37472d
Packit Service 37472d
    c = (c << 14) | (c >> 2 & 0x3fff);
Packit Service 37472d
    c -= ((b & (d ^ 0xffff)) + (a & d) + ekey[j--]);
Packit Service 37472d
Packit Service 37472d
    d = (d << 15) | (d >> 1 & 0x7fff);
Packit Service 37472d
    d -= ((c & (a ^ 0xffff)) + (b & a) + ekey[j--]);
Packit Service 37472d
Packit Service 37472d
    if(i == 5 || i == 11) {
Packit Service 37472d
      a -= ekey[b & 0x003f];
Packit Service 37472d
      b -= ekey[c & 0x003f];
Packit Service 37472d
      c -= ekey[d & 0x003f];
Packit Service 37472d
      d -= ekey[a & 0x003f];
Packit Service 37472d
    }
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  *out++ = d & 0xff;
Packit Service 37472d
  *out++ = (d >> 8) & 0xff;
Packit Service 37472d
  *out++ = c & 0xff;
Packit Service 37472d
  *out++ = (c >> 8) & 0xff;
Packit Service 37472d
  *out++ = b & 0xff;
Packit Service 37472d
  *out++ = (b >> 8) & 0xff;
Packit Service 37472d
  *out++ = a & 0xff;
Packit Service 37472d
  *out++ = (a >> 8) & 0xff;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwDecryptExpanded(const int *ekey, guchar *iv,
Packit Service 37472d
		       struct mwOpaque *in_data,
Packit Service 37472d
		       struct mwOpaque *out_data) {
Packit Service 37472d
Packit Service 37472d
  guchar *i = in_data->data;
Packit Service 37472d
  gsize i_len = in_data->len;
Packit Service 37472d
Packit Service 37472d
  guchar *o;
Packit Service 37472d
  gsize o_len;
Packit Service 37472d
Packit Service 37472d
  int x, y;
Packit Service 37472d
Packit Service 37472d
  if(i_len % 8) {
Packit Service 37472d
    /* this doesn't check to ensure that in_data->len is a multiple of
Packit Service 37472d
       8, which is damn well ought to be. */
Packit Service 37472d
    g_warning("attempting decryption of mis-sized data, %u bytes",
Packit Service 37472d
	      (guint) i_len);
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  o = g_malloc(i_len);
Packit Service 37472d
  o_len = i_len;
Packit Service 37472d
  for(x = i_len; x--; o[x] = i[x]);
Packit Service 37472d
  /* memcpy(o, i, i_len); */
Packit Service 37472d
Packit Service 37472d
  out_data->data = o;
Packit Service 37472d
  out_data->len = o_len;
Packit Service 37472d
Packit Service 37472d
  for(x = o_len; x > 0; x -= 8) {
Packit Service 37472d
    /* decrypt a block */
Packit Service 37472d
    mwDecryptBlock(ekey, o);
Packit Service 37472d
Packit Service 37472d
    /* modify the initialization vector */
Packit Service 37472d
    for(y = 8; y--; o[y] ^= iv[y]);
Packit Service 37472d
    for(y = 8; y--; iv[y] = i[y]);
Packit Service 37472d
    /* memcpy(iv, i, 8); */
Packit Service 37472d
    i += 8;
Packit Service 37472d
    o += 8;
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  /* shorten the length by the value of the filler in the padding
Packit Service 37472d
     bytes */
Packit Service 37472d
  out_data->len -= *(o - 1);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwDecrypt(const guchar *key, gsize keylen, guchar *iv,
Packit Service 37472d
	       struct mwOpaque *in, struct mwOpaque *out) {
Packit Service 37472d
Packit Service 37472d
  int ekey[64];
Packit Service 37472d
  mwKeyExpand(ekey, key, keylen);
Packit Service 37472d
  mwDecryptExpanded(ekey, iv, in, out);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwCipher_RC2_40 {
Packit Service 37472d
  struct mwCipher cipher;
Packit Service 37472d
  int session_key[64];
Packit Service 37472d
  gboolean ready;
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwCipherInstance_RC2_40 {
Packit Service 37472d
  struct mwCipherInstance instance;
Packit Service 37472d
  int incoming_key[64];
Packit Service 37472d
  guchar outgoing_iv[8];
Packit Service 37472d
  guchar incoming_iv[8];
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static const char *get_name_RC2_40() {
Packit Service 37472d
  return "RC2/40 Cipher";
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static const char *get_desc_RC2_40() {
Packit Service 37472d
  return "RC2, 40-bit effective key";
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static int encrypt_RC2_40(struct mwCipherInstance *ci,
Packit Service 37472d
			  struct mwOpaque *data) {
Packit Service 37472d
Packit Service 37472d
  struct mwCipherInstance_RC2_40 *cir;
Packit Service 37472d
  struct mwCipher_RC2_40 *cr;
Packit Service 37472d
  struct mwOpaque o = { 0, 0 };
Packit Service 37472d
Packit Service 37472d
  cir = (struct mwCipherInstance_RC2_40 *) ci;
Packit Service 37472d
  cr = (struct mwCipher_RC2_40 *) ci->cipher;
Packit Service 37472d
Packit Service 37472d
  mwEncryptExpanded(cr->session_key, cir->outgoing_iv, data, &o);
Packit Service 37472d
Packit Service 37472d
  mwOpaque_clear(data);
Packit Service 37472d
  data->data = o.data;
Packit Service 37472d
  data->len = o.len;
Packit Service 37472d
Packit Service 37472d
  return 0;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static int decrypt_RC2_40(struct mwCipherInstance *ci,
Packit Service 37472d
			  struct mwOpaque *data) {
Packit Service 37472d
  
Packit Service 37472d
  struct mwCipherInstance_RC2_40 *cir;
Packit Service 37472d
  struct mwCipher_RC2_40 *cr;
Packit Service 37472d
  struct mwOpaque o = { 0, 0 };
Packit Service 37472d
Packit Service 37472d
  cir = (struct mwCipherInstance_RC2_40 *) ci;
Packit Service 37472d
  cr = (struct mwCipher_RC2_40 *) ci->cipher;
Packit Service 37472d
Packit Service 37472d
  mwDecryptExpanded(cir->incoming_key, cir->incoming_iv, data, &o);
Packit Service 37472d
Packit Service 37472d
  mwOpaque_clear(data);
Packit Service 37472d
  data->data = o.data;
Packit Service 37472d
  data->len = o.len;
Packit Service 37472d
Packit Service 37472d
  return 0;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static struct mwCipherInstance *
Packit Service 37472d
new_instance_RC2_40(struct mwCipher *cipher,
Packit Service 37472d
		    struct mwChannel *chan) {
Packit Service 37472d
Packit Service 37472d
  struct mwCipher_RC2_40 *cr;
Packit Service 37472d
  struct mwCipherInstance_RC2_40 *cir;
Packit Service 37472d
  struct mwCipherInstance *ci;
Packit Service 37472d
Packit Service 37472d
  cr = (struct mwCipher_RC2_40 *) cipher;
Packit Service 37472d
Packit Service 37472d
  /* a bit of lazy initialization here */
Packit Service 37472d
  if(! cr->ready) {
Packit Service 37472d
    struct mwLoginInfo *info = mwSession_getLoginInfo(cipher->session);
Packit Service 37472d
    mwKeyExpand(cr->session_key, (guchar *) info->login_id, 5);
Packit Service 37472d
    cr->ready = TRUE;
Packit Service 37472d
  }
Packit Service 37472d
Packit Service 37472d
  cir = g_new0(struct mwCipherInstance_RC2_40, 1);
Packit Service 37472d
  ci = &cir->instance;
Packit Service 37472d
Packit Service 37472d
  ci->cipher = cipher;
Packit Service 37472d
  ci->channel = chan;
Packit Service 37472d
Packit Service 37472d
  mwIV_init(cir->incoming_iv);
Packit Service 37472d
  mwIV_init(cir->outgoing_iv);
Packit Service 37472d
Packit Service 37472d
  return ci;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static struct mwEncryptItem *new_item_RC2_40(struct mwCipherInstance *ci) {
Packit Service 37472d
  struct mwEncryptItem *e;
Packit Service 37472d
Packit Service 37472d
  e = g_new0(struct mwEncryptItem, 1);
Packit Service 37472d
  e->id = mwCipher_RC2_40;
Packit Service 37472d
  return e;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static struct mwEncryptItem *
Packit Service 37472d
offer_RC2_40(struct mwCipherInstance *ci) {
Packit Service 37472d
  return new_item_RC2_40(ci);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void accepted_RC2_40(struct mwCipherInstance *ci,
Packit Service 37472d
			    struct mwEncryptItem *item) {
Packit Service 37472d
Packit Service 37472d
  struct mwCipherInstance_RC2_40 *cir;
Packit Service 37472d
  struct mwLoginInfo *info;
Packit Service 37472d
Packit Service 37472d
  cir = (struct mwCipherInstance_RC2_40 *) ci;
Packit Service 37472d
  info = mwChannel_getUser(ci->channel);
Packit Service 37472d
Packit Service 37472d
  if(info->login_id) {
Packit Service 37472d
    mwKeyExpand(cir->incoming_key, (guchar *) info->login_id, 5);
Packit Service 37472d
  }
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static struct mwEncryptItem *
Packit Service 37472d
accept_RC2_40(struct mwCipherInstance *ci) {
Packit Service 37472d
Packit Service 37472d
  accepted_RC2_40(ci, NULL);
Packit Service 37472d
  return new_item_RC2_40(ci);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwCipher *mwCipher_new_RC2_40(struct mwSession *s) {
Packit Service 37472d
  struct mwCipher_RC2_40 *cr = g_new0(struct mwCipher_RC2_40, 1);
Packit Service 37472d
  struct mwCipher *c = &cr->cipher;
Packit Service 37472d
Packit Service 37472d
  c->session = s;
Packit Service 37472d
  c->type = mwCipher_RC2_40;
Packit Service 37472d
  c->get_name = get_name_RC2_40;
Packit Service 37472d
  c->get_desc = get_desc_RC2_40;
Packit Service 37472d
  c->new_instance = new_instance_RC2_40;
Packit Service 37472d
Packit Service 37472d
  c->offer = offer_RC2_40;
Packit Service 37472d
Packit Service 37472d
  c->accepted = accepted_RC2_40;
Packit Service 37472d
  c->accept = accept_RC2_40;
Packit Service 37472d
Packit Service 37472d
  c->encrypt = encrypt_RC2_40;
Packit Service 37472d
  c->decrypt = decrypt_RC2_40;
Packit Service 37472d
Packit Service 37472d
  return c;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwCipher_RC2_128 {
Packit Service 37472d
  struct mwCipher cipher;
Packit Service 37472d
  mw_mp_int private_key;
Packit Service 37472d
  struct mwOpaque public_key;
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwCipherInstance_RC2_128 {
Packit Service 37472d
  struct mwCipherInstance instance;
Packit Service 37472d
  int shared[64];      /* shared secret determined via DH exchange */
Packit Service 37472d
  guchar outgoing_iv[8];
Packit Service 37472d
  guchar incoming_iv[8];
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static const char *get_name_RC2_128() {
Packit Service 37472d
  return "RC2/128 Cipher";
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static const char *get_desc_RC2_128() {
Packit Service 37472d
  return "RC2, DH shared secret key";
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static struct mwCipherInstance *
Packit Service 37472d
new_instance_RC2_128(struct mwCipher *cipher,
Packit Service 37472d
		     struct mwChannel *chan) {
Packit Service 37472d
Packit Service 37472d
  struct mwCipher_RC2_128 *cr;
Packit Service 37472d
  struct mwCipherInstance_RC2_128 *cir;
Packit Service 37472d
  struct mwCipherInstance *ci;
Packit Service 37472d
Packit Service 37472d
  cr = (struct mwCipher_RC2_128 *) cipher;
Packit Service 37472d
Packit Service 37472d
  cir = g_new0(struct mwCipherInstance_RC2_128, 1);
Packit Service 37472d
  ci = &cir->instance;
Packit Service 37472d
  
Packit Service 37472d
  ci->cipher = cipher;
Packit Service 37472d
  ci->channel = chan;
Packit Service 37472d
Packit Service 37472d
  mwIV_init(cir->incoming_iv);
Packit Service 37472d
  mwIV_init(cir->outgoing_iv);
Packit Service 37472d
Packit Service 37472d
  return ci;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void offered_RC2_128(struct mwCipherInstance *ci,
Packit Service 37472d
			    struct mwEncryptItem *item) {
Packit Service 37472d
  
Packit Service 37472d
  mw_mp_int remote_key;
Packit Service 37472d
  mw_mp_int shared;
Packit Service 37472d
  struct mwOpaque sho = { 0, 0 };
Packit Service 37472d
Packit Service 37472d
  struct mwCipher *c;
Packit Service 37472d
  struct mwCipher_RC2_128 *cr;
Packit Service 37472d
  struct mwCipherInstance_RC2_128 *cir;
Packit Service 37472d
Packit Service 37472d
  c = ci->cipher;
Packit Service 37472d
  cr = (struct mwCipher_RC2_128 *) c;
Packit Service 37472d
  cir = (struct mwCipherInstance_RC2_128 *) ci;
Packit Service 37472d
Packit Service 37472d
  mw_mp_init(&remote_key);
Packit Service 37472d
  mw_mp_init(&shared);
Packit Service 37472d
Packit Service 37472d
  mwDHImportKey(&remote_key, &item->info);
Packit Service 37472d
  mwDHCalculateShared(&shared, &remote_key, &cr->private_key);
Packit Service 37472d
  mwDHExportKey(&shared, &sho);
Packit Service 37472d
Packit Service 37472d
  /* key expanded from the last 16 bytes of the DH shared secret. This
Packit Service 37472d
     took me forever to figure out. 16 bytes is 128 bit. */
Packit Service 37472d
  /* the sh_len-16 is important, because the key len could
Packit Service 37472d
     hypothetically start with 8bits or more unset, meaning the
Packit Service 37472d
     exported key might be less than 64 bytes in length */
Packit Service 37472d
  mwKeyExpand(cir->shared, sho.data+(sho.len-16), 16);
Packit Service 37472d
  
Packit Service 37472d
  mw_mp_clear(&remote_key);
Packit Service 37472d
  mw_mp_clear(&shared);
Packit Service 37472d
  mwOpaque_clear(&sho);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static struct mwEncryptItem *
Packit Service 37472d
offer_RC2_128(struct mwCipherInstance *ci) {
Packit Service 37472d
Packit Service 37472d
  struct mwCipher *c;
Packit Service 37472d
  struct mwCipher_RC2_128 *cr;
Packit Service 37472d
  struct mwEncryptItem *ei;
Packit Service 37472d
Packit Service 37472d
  c = ci->cipher;
Packit Service 37472d
  cr = (struct mwCipher_RC2_128 *) c;
Packit Service 37472d
Packit Service 37472d
  ei = g_new0(struct mwEncryptItem, 1);
Packit Service 37472d
  ei->id = mwCipher_RC2_128;
Packit Service 37472d
  mwOpaque_clone(&ei->info, &cr->public_key);
Packit Service 37472d
Packit Service 37472d
  return ei;
Packit Service 37472d
}			  
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void accepted_RC2_128(struct mwCipherInstance *ci,
Packit Service 37472d
			     struct mwEncryptItem *item) {
Packit Service 37472d
Packit Service 37472d
  offered_RC2_128(ci, item);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static struct mwEncryptItem *
Packit Service 37472d
accept_RC2_128(struct mwCipherInstance *ci) {
Packit Service 37472d
Packit Service 37472d
  return offer_RC2_128(ci);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static int encrypt_RC2_128(struct mwCipherInstance *ci,
Packit Service 37472d
			   struct mwOpaque *data) {
Packit Service 37472d
Packit Service 37472d
  struct mwCipherInstance_RC2_128 *cir;
Packit Service 37472d
  struct mwOpaque o = { 0, 0 };
Packit Service 37472d
Packit Service 37472d
  cir = (struct mwCipherInstance_RC2_128 *) ci;
Packit Service 37472d
Packit Service 37472d
  mwEncryptExpanded(cir->shared, cir->outgoing_iv, data, &o);
Packit Service 37472d
Packit Service 37472d
  mwOpaque_clear(data);
Packit Service 37472d
  data->data = o.data;
Packit Service 37472d
  data->len = o.len;
Packit Service 37472d
Packit Service 37472d
  return 0;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static int decrypt_RC2_128(struct mwCipherInstance *ci,
Packit Service 37472d
			   struct mwOpaque *data) {
Packit Service 37472d
Packit Service 37472d
  struct mwCipherInstance_RC2_128 *cir;
Packit Service 37472d
  struct mwOpaque o = { 0, 0 };
Packit Service 37472d
Packit Service 37472d
  cir = (struct mwCipherInstance_RC2_128 *) ci;
Packit Service 37472d
Packit Service 37472d
  mwDecryptExpanded(cir->shared, cir->incoming_iv, data, &o);
Packit Service 37472d
Packit Service 37472d
  mwOpaque_clear(data);
Packit Service 37472d
  data->data = o.data;
Packit Service 37472d
  data->len = o.len;
Packit Service 37472d
Packit Service 37472d
  return 0;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
static void clear_RC2_128(struct mwCipher *c) {
Packit Service 37472d
  struct mwCipher_RC2_128 *cr;
Packit Service 37472d
  cr = (struct mwCipher_RC2_128 *) c;
Packit Service 37472d
Packit Service 37472d
  mw_mp_clear(&cr->private_key);
Packit Service 37472d
  mwOpaque_clear(&cr->public_key);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwCipher *mwCipher_new_RC2_128(struct mwSession *s) {
Packit Service 37472d
  struct mwCipher_RC2_128 *cr;
Packit Service 37472d
  struct mwCipher *c;
Packit Service 37472d
Packit Service 37472d
  mw_mp_int pubkey;
Packit Service 37472d
Packit Service 37472d
  cr = g_new0(struct mwCipher_RC2_128, 1);
Packit Service 37472d
  c = &cr->cipher;
Packit Service 37472d
Packit Service 37472d
  c->session = s;
Packit Service 37472d
  c->type = mwCipher_RC2_128;
Packit Service 37472d
  c->get_name = get_name_RC2_128;
Packit Service 37472d
  c->get_desc = get_desc_RC2_128;
Packit Service 37472d
  c->new_instance = new_instance_RC2_128;
Packit Service 37472d
Packit Service 37472d
  c->offered = offered_RC2_128;
Packit Service 37472d
  c->offer = offer_RC2_128;
Packit Service 37472d
Packit Service 37472d
  c->accepted = accepted_RC2_128;
Packit Service 37472d
  c->accept = accept_RC2_128;
Packit Service 37472d
Packit Service 37472d
  c->encrypt = encrypt_RC2_128;
Packit Service 37472d
  c->decrypt = decrypt_RC2_128;
Packit Service 37472d
Packit Service 37472d
  c->clear = clear_RC2_128;
Packit Service 37472d
  
Packit Service 37472d
  mw_mp_init(&cr->private_key);
Packit Service 37472d
  mw_mp_init(&pubkey);
Packit Service 37472d
  mwDHRandKeypair(&cr->private_key, &pubkey);
Packit Service 37472d
  mwDHExportKey(&pubkey, &cr->public_key);
Packit Service 37472d
  mw_mp_clear(&pubkey);
Packit Service 37472d
Packit Service 37472d
  return c;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwSession *mwCipher_getSession(struct mwCipher *cipher) {
Packit Service 37472d
  g_return_val_if_fail(cipher != NULL, NULL);
Packit Service 37472d
  return cipher->session;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint16 mwCipher_getType(struct mwCipher *cipher) {
Packit Service 37472d
  /* oh man, this is a bad failover... who the hell decided to make
Packit Service 37472d
     zero a real cipher id? */
Packit Service 37472d
  g_return_val_if_fail(cipher != NULL, 0xffff);
Packit Service 37472d
  return cipher->type;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
const char *mwCipher_getName(struct mwCipher *cipher) {
Packit Service 37472d
  g_return_val_if_fail(cipher != NULL, NULL);
Packit Service 37472d
  g_return_val_if_fail(cipher->get_name != NULL, NULL);
Packit Service 37472d
  return cipher->get_name();
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
const char *mwCipher_getDesc(struct mwCipher *cipher) {
Packit Service 37472d
  g_return_val_if_fail(cipher != NULL, NULL);
Packit Service 37472d
  g_return_val_if_fail(cipher->get_desc != NULL, NULL);
Packit Service 37472d
  return cipher->get_desc();
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwCipher_free(struct mwCipher *cipher) {
Packit Service 37472d
  if(! cipher) return;
Packit Service 37472d
Packit Service 37472d
  if(cipher->clear)
Packit Service 37472d
    cipher->clear(cipher);
Packit Service 37472d
Packit Service 37472d
  g_free(cipher);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwCipherInstance *mwCipher_newInstance(struct mwCipher *cipher,
Packit Service 37472d
					      struct mwChannel *chan) {
Packit Service 37472d
  g_return_val_if_fail(cipher != NULL, NULL);
Packit Service 37472d
  g_return_val_if_fail(chan != NULL, NULL);
Packit Service 37472d
  g_return_val_if_fail(cipher->new_instance != NULL, NULL);
Packit Service 37472d
  return cipher->new_instance(cipher, chan);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwCipher *mwCipherInstance_getCipher(struct mwCipherInstance *ci) {
Packit Service 37472d
  g_return_val_if_fail(ci != NULL, NULL);
Packit Service 37472d
  return ci->cipher;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwChannel *mwCipherInstance_getChannel(struct mwCipherInstance *ci) {
Packit Service 37472d
  g_return_val_if_fail(ci != NULL, NULL);
Packit Service 37472d
  return ci->channel;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwCipherInstance_offered(struct mwCipherInstance *ci,
Packit Service 37472d
			      struct mwEncryptItem *item) {
Packit Service 37472d
  struct mwCipher *cipher;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(ci != NULL);
Packit Service 37472d
Packit Service 37472d
  cipher = ci->cipher;
Packit Service 37472d
  g_return_if_fail(cipher != NULL);
Packit Service 37472d
Packit Service 37472d
  if(cipher->offered) cipher->offered(ci, item);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwEncryptItem *
Packit Service 37472d
mwCipherInstance_offer(struct mwCipherInstance *ci) {
Packit Service 37472d
  struct mwCipher *cipher;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(ci != NULL, NULL);
Packit Service 37472d
Packit Service 37472d
  cipher = ci->cipher;
Packit Service 37472d
  g_return_val_if_fail(cipher != NULL, NULL);
Packit Service 37472d
Packit Service 37472d
  return cipher->offer(ci);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwCipherInstance_accepted(struct mwCipherInstance *ci,
Packit Service 37472d
			       struct mwEncryptItem *item) {
Packit Service 37472d
  struct mwCipher *cipher;
Packit Service 37472d
Packit Service 37472d
  g_return_if_fail(ci != NULL);
Packit Service 37472d
Packit Service 37472d
  cipher = ci->cipher;
Packit Service 37472d
  g_return_if_fail(cipher != NULL);
Packit Service 37472d
Packit Service 37472d
  if(cipher->accepted) cipher->accepted(ci, item);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwEncryptItem *
Packit Service 37472d
mwCipherInstance_accept(struct mwCipherInstance *ci) {
Packit Service 37472d
  struct mwCipher *cipher;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(ci != NULL, NULL);
Packit Service 37472d
Packit Service 37472d
  cipher = ci->cipher;
Packit Service 37472d
  g_return_val_if_fail(cipher != NULL, NULL);
Packit Service 37472d
Packit Service 37472d
  return cipher->accept(ci);
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
int mwCipherInstance_encrypt(struct mwCipherInstance *ci,
Packit Service 37472d
			     struct mwOpaque *data) {
Packit Service 37472d
  struct mwCipher *cipher;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(data != NULL, 0);
Packit Service 37472d
Packit Service 37472d
  if(! ci) return 0;
Packit Service 37472d
  cipher = ci->cipher;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(cipher != NULL, -1);
Packit Service 37472d
Packit Service 37472d
  return (cipher->encrypt)?
Packit Service 37472d
    cipher->encrypt(ci, data): 0;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
int mwCipherInstance_decrypt(struct mwCipherInstance *ci,
Packit Service 37472d
			     struct mwOpaque *data) {
Packit Service 37472d
  struct mwCipher *cipher;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(data != NULL, 0);
Packit Service 37472d
Packit Service 37472d
  if(! ci) return 0;
Packit Service 37472d
  cipher = ci->cipher;
Packit Service 37472d
Packit Service 37472d
  g_return_val_if_fail(cipher != NULL, -1);
Packit Service 37472d
Packit Service 37472d
  return (cipher->decrypt)?
Packit Service 37472d
    cipher->decrypt(ci, data): 0;
Packit Service 37472d
}
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwCipherInstance_free(struct mwCipherInstance *ci) {
Packit Service 37472d
  struct mwCipher *cipher;
Packit Service 37472d
Packit Service 37472d
  if(! ci) return;
Packit Service 37472d
Packit Service 37472d
  cipher = ci->cipher;
Packit Service 37472d
Packit Service 37472d
  if(cipher && cipher->clear_instance)
Packit Service 37472d
    cipher->clear_instance(ci);
Packit Service 37472d
Packit Service 37472d
  g_free(ci);
Packit Service 37472d
}
Packit Service 37472d