#
settings = {
"server" = {
- crypto_default_cipher = "aes-256-cbc";
+ crypto_default_cipher = "aes-256-ctr";
crypto_default_hash = "sha1";
crypto_default_hmac = "hmac-sha1-96";
};
* SILC Crypto API for AES
*/
+/* CBC mode */
+
/* Sets the key for the cipher. */
-SILC_CIPHER_API_SET_KEY(aes)
+SILC_CIPHER_API_SET_KEY(aes_cbc)
{
if (encryption)
aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
/* Returns the size of the cipher context. */
-SILC_CIPHER_API_CONTEXT_LEN(aes)
+SILC_CIPHER_API_CONTEXT_LEN(aes_cbc)
{
return sizeof(AesContext);
}
/* Encrypts with the cipher in CBC mode. Source and destination buffers
maybe one and same. */
-SILC_CIPHER_API_ENCRYPT_CBC(aes)
+SILC_CIPHER_API_ENCRYPT(aes_cbc)
{
int nb = len >> 4;
+ SILC_ASSERT((len & (16 - 1)) == 0);
+ if (len & (16 - 1))
+ return FALSE;
+
while(nb--) {
lp32(iv)[0] ^= lp32(src)[0];
lp32(iv)[1] ^= lp32(src)[1];
/* Decrypts with the cipher in CBC mode. Source and destination buffers
maybe one and same. */
-SILC_CIPHER_API_DECRYPT_CBC(aes)
+SILC_CIPHER_API_DECRYPT(aes_cbc)
{
unsigned char tmp[16];
int nb = len >> 4;
+ if (len & (16 - 1))
+ return FALSE;
+
while(nb--) {
memcpy(tmp, src, 16);
aes_decrypt(src, dst, &((AesContext *)context)->u.dec);
return TRUE;
}
+/* CTR mode */
+
+/* Sets the key for the cipher. */
+
+SILC_CIPHER_API_SET_KEY(aes_ctr)
+{
+ AesContext *aes = context;
+ memset(&aes->u.enc, 0, sizeof(aes->u.enc));
+ aes_encrypt_key(key, keylen, &aes->u.enc);
+ return TRUE;
+}
+
+/* Returns the size of the cipher context. */
+
+SILC_CIPHER_API_CONTEXT_LEN(aes_ctr)
+{
+ return sizeof(AesContext);
+}
+
+/* Encrypts with the cipher in CTR mode. Source and destination buffers
+ maybe one and same. Assumes MSB first ordered counter. */
+
+SILC_CIPHER_API_ENCRYPT(aes_ctr)
+{
+ AesContext *aes = context;
+ SilcUInt32 ctr[4];
+ int i;
+
+ SILC_GET32_MSB(ctr[0], iv);
+ SILC_GET32_MSB(ctr[1], iv + 4);
+ SILC_GET32_MSB(ctr[2], iv + 8);
+ SILC_GET32_MSB(ctr[3], iv + 12);
+
+ i = aes->u.enc.inf.b[2];
+ if (!i)
+ i = 16;
+
+ while (len-- > 0) {
+ if (i == 16) {
+ if (++ctr[3] == 0)
+ if (++ctr[2] == 0)
+ if (++ctr[1] == 0)
+ ++ctr[0];
+
+ SILC_PUT32_MSB(ctr[0], iv);
+ SILC_PUT32_MSB(ctr[1], iv + 4);
+ SILC_PUT32_MSB(ctr[2], iv + 8);
+ SILC_PUT32_MSB(ctr[3], iv + 12);
+
+ aes_encrypt(iv, iv, &aes->u.enc);
+ i = 0;
+ }
+ *dst++ = *src++ ^ iv[i++];
+ }
+ aes->u.enc.inf.b[2] = i;
+
+ SILC_PUT32_MSB(ctr[0], iv);
+ SILC_PUT32_MSB(ctr[1], iv + 4);
+ SILC_PUT32_MSB(ctr[2], iv + 8);
+ SILC_PUT32_MSB(ctr[3], iv + 12);
+
+ return TRUE;
+}
+
+/* Decrypts with the cipher in CTR mode. Source and destination buffers
+ maybe one and same. */
+
+SILC_CIPHER_API_DECRYPT(aes_ctr)
+{
+ return silc_aes_ctr_encrypt(context, src, dst, len, iv);
+}
+
/****************************************************************************/
#if defined(__cplusplus)
#define AES_H
/*
- * SILC Crypto API for Rijndael
+ * SILC Crypto API for AES
*/
-SILC_CIPHER_API_SET_KEY(aes);
-SILC_CIPHER_API_CONTEXT_LEN(aes);
-SILC_CIPHER_API_ENCRYPT_CBC(aes);
-SILC_CIPHER_API_DECRYPT_CBC(aes);
+SILC_CIPHER_API_SET_KEY(aes_cbc);
+SILC_CIPHER_API_ENCRYPT(aes_cbc);
+SILC_CIPHER_API_DECRYPT(aes_cbc);
+SILC_CIPHER_API_CONTEXT_LEN(aes_cbc);
+SILC_CIPHER_API_SET_KEY(aes_ctr);
+SILC_CIPHER_API_ENCRYPT(aes_ctr);
+SILC_CIPHER_API_DECRYPT(aes_ctr);
+SILC_CIPHER_API_CONTEXT_LEN(aes_ctr);
#endif
/* Sets the key for the cipher. */
-SILC_CIPHER_API_SET_KEY(blowfish)
+SILC_CIPHER_API_SET_KEY(blowfish_cbc)
{
blowfish_set_key((BlowfishContext *)context, (unsigned char *)key, keylen);
return TRUE;
/* Returns the size of the cipher context. */
-SILC_CIPHER_API_CONTEXT_LEN(blowfish)
+SILC_CIPHER_API_CONTEXT_LEN(blowfish_cbc)
{
return sizeof(BlowfishContext);
}
/* Encrypts with the cipher in CBC mode. Source and destination buffers
maybe one and same. */
-SILC_CIPHER_API_ENCRYPT_CBC(blowfish)
+SILC_CIPHER_API_ENCRYPT(blowfish_cbc)
{
SilcUInt32 tiv[4];
int i;
/* Decrypts with the cipher in CBC mode. Source and destination buffers
maybe one and same. */
-SILC_CIPHER_API_DECRYPT_CBC(blowfish)
+SILC_CIPHER_API_DECRYPT(blowfish_cbc)
{
SilcUInt32 tmp[4], tmp2[4], tiv[4];
int i;
* SILC Crypto API for Blowfish
*/
-SILC_CIPHER_API_SET_KEY(blowfish);
-SILC_CIPHER_API_CONTEXT_LEN(blowfish);
-SILC_CIPHER_API_ENCRYPT_CBC(blowfish);
-SILC_CIPHER_API_DECRYPT_CBC(blowfish);
+SILC_CIPHER_API_SET_KEY(blowfish_cbc);
+SILC_CIPHER_API_CONTEXT_LEN(blowfish_cbc);
+SILC_CIPHER_API_ENCRYPT(blowfish_cbc);
+SILC_CIPHER_API_DECRYPT(blowfish_cbc);
#endif
/* Sets the key for the cipher. */
-SILC_CIPHER_API_SET_KEY(cast)
+SILC_CIPHER_API_SET_KEY(cast_cbc)
{
SilcUInt32 k[8];
/* Returns the size of the cipher context. */
-SILC_CIPHER_API_CONTEXT_LEN(cast)
+SILC_CIPHER_API_CONTEXT_LEN(cast_cbc)
{
return sizeof(CastContext);
}
/* Encrypts with the cipher in CBC mode. Source and destination buffers
maybe one and same. */
-SILC_CIPHER_API_ENCRYPT_CBC(cast)
+SILC_CIPHER_API_ENCRYPT(cast_cbc)
{
SilcUInt32 tiv[4];
int i;
+ SILC_ASSERT((len & (16 - 1)) == 0);
+ if (len & (16 - 1))
+ return FALSE;
+
SILC_CBC_GET_IV(tiv, iv);
SILC_CBC_ENC_PRE(tiv, src);
/* Decrypts with the cipher in CBC mode. Source and destination buffers
maybe one and same. */
-SILC_CIPHER_API_DECRYPT_CBC(cast)
+SILC_CIPHER_API_DECRYPT(cast_cbc)
{
SilcUInt32 tmp[4], tmp2[4], tiv[4];
int i;
+ if (len & (16 - 1))
+ return FALSE;
+
SILC_CBC_GET_IV(tiv, iv);
SILC_CBC_DEC_PRE(tmp, src);
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1999 - 2000 Pekka Riikonen
+ Copyright (C) 1999 - 2000, 2006 Pekka Riikonen
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
* SILC Crypto API for Cast-256
*/
-SILC_CIPHER_API_SET_KEY(cast);
-SILC_CIPHER_API_CONTEXT_LEN(cast);
-SILC_CIPHER_API_ENCRYPT_CBC(cast);
-SILC_CIPHER_API_DECRYPT_CBC(cast);
+SILC_CIPHER_API_SET_KEY(cast_cbc);
+SILC_CIPHER_API_CONTEXT_LEN(cast_cbc);
+SILC_CIPHER_API_ENCRYPT(cast_cbc);
+SILC_CIPHER_API_DECRYPT(cast_cbc);
#endif
return 1;
}
-SILC_CIPHER_API_ENCRYPT_CBC(none)
+SILC_CIPHER_API_ENCRYPT(none)
{
memcpy(dst, src, len);
return TRUE;
}
-SILC_CIPHER_API_DECRYPT_CBC(none)
+SILC_CIPHER_API_DECRYPT(none)
{
memcpy(dst, src, len);
return TRUE;
GNU General Public License for more details.
*/
-/*
- * $Id$
- * $Log$
- * Revision 1.3 2006/12/15 15:22:48 priikone
- * Added assembler AES for x86 and x86_64.
- * Simplified Cipher implementation API.
- *
- * Revision 1.2 2005/05/10 18:31:17 priikone
- * Merged silc_1_0_branch to trunk.
- *
- * Revision 1.1.1.1.4.1 2005/04/30 15:31:26 priikone
- * Header changes.
- *
- * Revision 1.1.1.1 2000/06/27 11:36:54 priikone
- * Importet from internal CVS/Added Log headers.
- *
- *
- */
#ifndef NONE_H
#define NONE_H
SILC_CIPHER_API_SET_KEY(none);
SILC_CIPHER_API_CONTEXT_LEN(none);
-SILC_CIPHER_API_ENCRYPT_CBC(none);
-SILC_CIPHER_API_DECRYPT_CBC(none);
+SILC_CIPHER_API_ENCRYPT(none);
+SILC_CIPHER_API_DECRYPT(none);
#endif
/* Sets the key for the cipher. */
-SILC_CIPHER_API_SET_KEY(rc5)
+SILC_CIPHER_API_SET_KEY(rc5_cbc)
{
SilcUInt32 k[8];
/* Returns the size of the cipher context. */
-SILC_CIPHER_API_CONTEXT_LEN(rc5)
+SILC_CIPHER_API_CONTEXT_LEN(rc5_cbc)
{
return sizeof(RC5Context);
}
/* Encrypts with the cipher in CBC mode. Source and destination buffers
maybe one and same. */
-SILC_CIPHER_API_ENCRYPT_CBC(rc5)
+SILC_CIPHER_API_ENCRYPT(rc5_cbc)
{
SilcUInt32 tiv[4];
int i;
/* Decrypts with the cipher in CBC mode. Source and destination buffers
maybe one and same. */
-SILC_CIPHER_API_DECRYPT_CBC(rc5)
+SILC_CIPHER_API_DECRYPT(rc5_cbc)
{
SilcUInt32 tmp[4], tmp2[4], tiv[4];
int i;
* SILC Crypto API for RC5
*/
-SILC_CIPHER_API_SET_KEY(rc5);
-SILC_CIPHER_API_CONTEXT_LEN(rc5);
-SILC_CIPHER_API_ENCRYPT_CBC(rc5);
-SILC_CIPHER_API_DECRYPT_CBC(rc5);
+SILC_CIPHER_API_SET_KEY(rc5_cbc);
+SILC_CIPHER_API_CONTEXT_LEN(rc5_cbc);
+SILC_CIPHER_API_ENCRYPT(rc5_cbc);
+SILC_CIPHER_API_DECRYPT(rc5_cbc);
#endif
SilcDList silc_cipher_list = NULL;
#endif /* SILC_EPOC */
+/* Macro to define cipher to cipher list */
+#define SILC_CIPHER_API_DEF(name, cipher, keylen, blocklen, ivlen) \
+{ name, silc_##cipher##_set_key, silc_##cipher##_encrypt, \
+ silc_##cipher##_decrypt, silc_##cipher##_context_len, \
+ keylen, blocklen, ivlen }
+
/* Static list of ciphers for silc_cipher_register_default(). */
const SilcCipherObject silc_default_ciphers[] =
{
- { "aes-256-cbc", silc_aes_set_key,
- silc_aes_encrypt_cbc, silc_aes_decrypt_cbc, silc_aes_context_len,
- 256, 16, 16 },
- { "aes-192-cbc", silc_aes_set_key,
- silc_aes_encrypt_cbc, silc_aes_decrypt_cbc, silc_aes_context_len,
- 192, 16, 16 },
- { "aes-128-cbc", silc_aes_set_key,
- silc_aes_encrypt_cbc, silc_aes_decrypt_cbc, silc_aes_context_len,
- 128, 16, 16 },
- { "twofish-256-cbc", silc_twofish_set_key,
- silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc,
- silc_twofish_context_len,
- 256, 16, 16 },
- { "twofish-192-cbc", silc_twofish_set_key,
- silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc,
- silc_twofish_context_len,
- 192, 16, 16 },
- { "twofish-128-cbc", silc_twofish_set_key,
- silc_twofish_encrypt_cbc, silc_twofish_decrypt_cbc,
- silc_twofish_context_len,
- 128, 16, 16 },
- { "cast-256-cbc", silc_cast_set_key,
- silc_cast_encrypt_cbc, silc_cast_decrypt_cbc,
- silc_cast_context_len,
- 256, 16, 16 },
- { "cast-192-cbc", silc_cast_set_key,
- silc_cast_encrypt_cbc, silc_cast_decrypt_cbc,
- silc_cast_context_len,
- 192, 16, 16 },
- { "cast-128-cbc", silc_cast_set_key,
- silc_cast_encrypt_cbc, silc_cast_decrypt_cbc,
- silc_cast_context_len,
- 128, 16, 16 },
+ SILC_CIPHER_API_DEF("aes-256-ctr", aes_ctr, 256, 16, 16),
+ SILC_CIPHER_API_DEF("aes-192-ctr", aes_ctr, 192, 16, 16),
+ SILC_CIPHER_API_DEF("aes-128-ctr", aes_ctr, 128, 16, 16),
+ SILC_CIPHER_API_DEF("aes-256-cbc", aes_cbc, 256, 16, 16),
+ SILC_CIPHER_API_DEF("aes-192-cbc", aes_cbc, 192, 16, 16),
+ SILC_CIPHER_API_DEF("aes-128-cbc", aes_cbc, 128, 16, 16),
+ SILC_CIPHER_API_DEF("twofish-256-cbc", twofish_cbc, 256, 16, 16),
+ SILC_CIPHER_API_DEF("twofish-192-cbc", twofish_cbc, 192, 16, 16),
+ SILC_CIPHER_API_DEF("twofish-128-cbc", twofish_cbc, 128, 16, 16),
+ SILC_CIPHER_API_DEF("cast-256-cbc", cast_cbc, 256, 16, 16),
+ SILC_CIPHER_API_DEF("cast-192-cbc", cast_cbc, 192, 16, 16),
+ SILC_CIPHER_API_DEF("cast-128-cbc", cast_cbc, 128, 16, 16),
#ifdef SILC_DEBUG
- { "none", silc_none_set_key,
- silc_none_encrypt_cbc, silc_none_decrypt_cbc,
- silc_none_context_len,
- 0, 0, 0 },
+ SILC_CIPHER_API_DEF("none", none, 0, 0, 0),
#endif /* SILC_DEBUG */
-
- { NULL, NULL, NULL, NULL, NULL, 0, 0, 0 }
+ { NULL, NULL, 0, 0, 0 }
};
/* Register a new cipher into SILC. This is used at the initialization of
unsigned char *dst, SilcUInt32 len,
unsigned char *iv)
{
- SILC_ASSERT((len & (cipher->cipher->block_len - 1)) == 0);
- if (silc_unlikely(len & (cipher->cipher->block_len - 1)))
- return FALSE;
return cipher->cipher->encrypt(cipher->context, src, dst, len,
iv ? iv : cipher->iv);
}
unsigned char *dst, SilcUInt32 len,
unsigned char *iv)
{
- if (silc_unlikely(len & (cipher->cipher->block_len - 1)))
- return FALSE;
return cipher->cipher->decrypt(cipher->context, src, dst, len,
iv ? iv : cipher->iv);
}
char *name;
SilcBool (*set_key)(void *, const unsigned char *, SilcUInt32, SilcBool);
SilcBool (*encrypt)(void *, const unsigned char *, unsigned char *,
- SilcUInt32, unsigned char *);
+ SilcUInt32, unsigned char *);
SilcBool (*decrypt)(void *, const unsigned char *, unsigned char *,
- SilcUInt32, unsigned char *);
+ SilcUInt32, unsigned char *);
SilcUInt32 (*context_len)();
unsigned int key_len : 12;
unsigned int block_len : 10;
of the module. All SILC Crypto API compliant modules must support
these function names (use macros below to assure this). */
#define SILC_CIPHER_SIM_SET_KEY "set_key"
-#define SILC_CIPHER_SIM_ENCRYPT_CBC "encrypt_cbc"
-#define SILC_CIPHER_SIM_DECRYPT_CBC "decrypt_cbc"
+#define SILC_CIPHER_SIM_ENCRYPT "encrypt"
+#define SILC_CIPHER_SIM_DECRYPT "decrypt"
#define SILC_CIPHER_SIM_CONTEXT_LEN "context_len"
+#define SILC_CIPHER_SIM_SET_IV "set_iv"
/* These macros can be used to implement the SILC Crypto API and to avoid
errors in the API these macros should be used always. */
-#define SILC_CIPHER_API_SET_KEY(cipher) \
+#define SILC_CIPHER_API_SET_KEY(cipher) \
SilcBool silc_##cipher##_set_key(void *context, \
- const unsigned char *key, \
- SilcUInt32 keylen, \
- SilcBool encryption)
-#define SILC_CIPHER_API_ENCRYPT_CBC(cipher) \
-SilcBool silc_##cipher##_encrypt_cbc(void *context, \
+ const unsigned char *key, \
+ SilcUInt32 keylen, \
+ SilcBool encryption)
+#define SILC_CIPHER_API_ENCRYPT(cipher) \
+SilcBool silc_##cipher##_encrypt(void *context, \
const unsigned char *src, \
- unsigned char *dst, \
+ unsigned char *dst, \
SilcUInt32 len, \
- unsigned char *iv)
-#define SILC_CIPHER_API_DECRYPT_CBC(cipher) \
-SilcBool silc_##cipher##_decrypt_cbc(void *context, \
- const unsigned char *src, \
+ unsigned char *iv)
+#define SILC_CIPHER_API_DECRYPT(cipher) \
+SilcBool silc_##cipher##_decrypt(void *context, \
+ const unsigned char *src, \
unsigned char *dst, \
SilcUInt32 len, \
unsigned char *iv)
-#define SILC_CIPHER_API_CONTEXT_LEN(cipher) \
+#define SILC_CIPHER_API_CONTEXT_LEN(cipher) \
SilcUInt32 silc_##cipher##_context_len()
+#define SILC_CIPHER_API_SET_IV(cipher) \
+SilcBool silc_##cipher##_set_iv(void *context, const unsigned char *iv)
/* Prototypes */
int p2_len = 32;
const unsigned char c2[] = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a\x3a\x86\x30\x28\xb5\xe1\xdc\x0a\x75\x86\x60\x2d\x25\x3c\xff\xf9\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1";
+/* CTR test vectors from RFC3686. */
+
+/* 16 bytes plaintext, 128 bits key */
+const unsigned char key3[] = "\xAE\x68\x52\xF8\x12\x10\x67\xCC\x4B\xF7\xA5\x76\x55\x77\xF3\x9E";
+int key3_len = 16 * 8;
+const unsigned char iv3[] = "\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+const unsigned char p3[] = "Single block msg";
+int p3_len = 16;
+const unsigned char c3[] = "\xE4\x09\x5D\x4F\xB7\xA7\xB3\x79\x2D\x61\x75\xA3\x26\x13\x11\xB8";
+
+/* 32 bytes plaintext, 128 bits key */
+const unsigned char key4[] = "\x7E\x24\x06\x78\x17\xFA\xE0\xD7\x43\xD6\xCE\x1F\x32\x53\x91\x63";
+int key4_len = 16 * 8;
+const unsigned char iv4[] = "\x00\x6C\xB6\xDB\xC0\x54\x3B\x59\xDA\x48\xD9\x0B\x00\x00\x00\x00";
+const unsigned char p4[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
+int p4_len = 32;
+const unsigned char c4[] = "\x51\x04\xA1\x06\x16\x8A\x72\xD9\x79\x0D\x41\xEE\x8E\xDA\xD3\x88\xEB\x2E\x1E\xFC\x46\xDA\x57\xC8\xFC\xE6\x30\xDF\x91\x41\xBE\x28";
+
+/* 36 bytes plaintext, 256 bits key */
+const unsigned char key5[] = "\xFF\x7A\x61\x7C\xE6\x91\x48\xE4\xF1\x72\x6E\x2F\x43\x58\x1D\xE2\xAA\x62\xD9\xF8\x05\x53\x2E\xDF\xF1\xEE\xD6\x87\xFB\x54\x15\x3D";
+int key5_len = 32 * 8;
+const unsigned char iv5[] = "\x00\x1C\xC5\xB7\x51\xA5\x1D\x70\xA1\xC1\x11\x48\x00\x00\x00\x00";
+const unsigned char p5[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23";
+int p5_len = 36;
+const unsigned char c5[] = "\xEB\x6C\x52\x82\x1D\x0B\xBB\xF7\xCE\x75\x94\x46\x2A\xCA\x4F\xAA\xB4\x07\xDF\x86\x65\x69\xFD\x07\xF4\x8C\xC0\xB5\x83\xD6\x07\x1F\x1E\xC0\xE6\xB8";
int main(int argc, char **argv)
{
SilcBool success = FALSE;
- SilcCipher cipher;
+ SilcCipher cipher, cipher2;
unsigned char dst[256], pdst[256];
int i;
SILC_LOG_DEBUG(("Registering builtin hash functions"));
silc_cipher_register_default();
- if (!silc_cipher_is_supported("aes-128-cbc")) {
- SILC_LOG_DEBUG(("aes-128-cbc is not supported"));
- goto err;
- }
-
SILC_LOG_DEBUG(("Allocating AES-CBC cipher"));
if (!silc_cipher_alloc("aes-128-cbc", &cipher)) {
SILC_LOG_DEBUG(("Allocating AES-CBC cipher failed"));
goto err;
}
+ if (!silc_cipher_alloc("aes-128-cbc", &cipher2)) {
+ SILC_LOG_DEBUG(("Allocating AES-CBC cipher failed"));
+ goto err;
+ }
/* First test vector */
SILC_LOG_DEBUG(("First test vector"));
memset(dst, 0, sizeof(dst));
memset(pdst, 0, sizeof(pdst));
silc_cipher_set_iv(cipher, iv1);
- assert(silc_cipher_set_key(cipher, key1, key1_len));
+ assert(silc_cipher_set_key(cipher, key1, key1_len, TRUE));
+ assert(silc_cipher_set_key(cipher2, key1, key1_len, FALSE));
assert(silc_cipher_encrypt(cipher, p1, dst, p1_len, NULL));
SILC_LOG_DEBUG(("block len %d, key len %d, name %s",
silc_cipher_get_block_len(cipher),
goto err;
}
SILC_LOG_DEBUG(("Encrypt is successful"));
- silc_cipher_set_iv(cipher, iv1);
- assert(silc_cipher_decrypt(cipher, dst, pdst, p1_len, NULL));
+ silc_cipher_set_iv(cipher2, iv1);
+ assert(silc_cipher_decrypt(cipher2, dst, pdst, p1_len, NULL));
SILC_LOG_HEXDUMP(("Decrypted plaintext"), (unsigned char *)pdst, p1_len);
SILC_LOG_HEXDUMP(("Expected plaintext"), (unsigned char *)p1, p1_len);
if (memcmp(pdst, p1, p1_len)) {
memset(dst, 0, sizeof(dst));
memset(pdst, 0, sizeof(pdst));
silc_cipher_set_iv(cipher, iv2);
- assert(silc_cipher_set_key(cipher, key2, key2_len));
+ assert(silc_cipher_set_key(cipher, key2, key2_len, TRUE));
+ assert(silc_cipher_set_key(cipher2, key2, key2_len, FALSE));
assert(silc_cipher_encrypt(cipher, p2, dst, p2_len, NULL));
SILC_LOG_DEBUG(("block len %d, key len %d, name %s",
silc_cipher_get_block_len(cipher),
goto err;
}
SILC_LOG_DEBUG(("Encrypt is successful"));
- silc_cipher_set_iv(cipher, iv2);
- assert(silc_cipher_decrypt(cipher, dst, pdst, p2_len, NULL));
+ silc_cipher_set_iv(cipher2, iv2);
+ assert(silc_cipher_decrypt(cipher2, dst, pdst, p2_len, NULL));
SILC_LOG_HEXDUMP(("Decrypted plaintext"), (unsigned char *)pdst, p2_len);
SILC_LOG_HEXDUMP(("Expected plaintext"), (unsigned char *)p2, p2_len);
if (memcmp(pdst, p2, p2_len)) {
goto err;
}
SILC_LOG_DEBUG(("Decrypt is successful"));
+ silc_cipher_free(cipher);
+ silc_cipher_free(cipher2);
+
+
+ SILC_LOG_DEBUG(("Allocating aes-128-ctr cipher"));
+ if (!silc_cipher_alloc("aes-128-ctr", &cipher)) {
+ SILC_LOG_DEBUG(("Allocating aes-128-ctr cipher failed"));
+ goto err;
+ }
+
+ /* Third test vector */
+ SILC_LOG_DEBUG(("Third test vector"));
+ memset(dst, 0, sizeof(dst));
+ memset(pdst, 0, sizeof(pdst));
+ silc_cipher_set_iv(cipher, iv3);
+ assert(silc_cipher_set_key(cipher, key3, key3_len, TRUE));
+ assert(silc_cipher_encrypt(cipher, p3, dst, p3_len, NULL));
+ SILC_LOG_DEBUG(("block len %d, key len %d, name %s",
+ silc_cipher_get_block_len(cipher),
+ silc_cipher_get_key_len(cipher),
+ silc_cipher_get_name(cipher)));
+ SILC_LOG_HEXDUMP(("Plaintext"), (unsigned char *)p3, p3_len);
+ SILC_LOG_HEXDUMP(("Ciphertext"), (unsigned char *)dst, p3_len);
+ SILC_LOG_HEXDUMP(("Expected ciphertext"), (unsigned char *)c3, p3_len);
+ if (memcmp(dst, c3, p3_len)) {
+ SILC_LOG_DEBUG(("Encrypt failed"));
+ goto err;
+ }
+ SILC_LOG_DEBUG(("Encrypt is successful"));
+ silc_cipher_set_iv(cipher, iv3);
+ assert(silc_cipher_decrypt(cipher, dst, pdst, p3_len, NULL));
+ SILC_LOG_HEXDUMP(("Decrypted plaintext"), (unsigned char *)pdst, p3_len);
+ SILC_LOG_HEXDUMP(("Expected plaintext"), (unsigned char *)p3, p3_len);
+ if (memcmp(pdst, p3, p3_len)) {
+ SILC_LOG_DEBUG(("Decrypt failed"));
+ goto err;
+ }
+ SILC_LOG_DEBUG(("Decrypt is successful"));
+
+
+ /* Fourth test vector */
+ SILC_LOG_DEBUG(("Fourth test vector"));
+ memset(dst, 0, sizeof(dst));
+ memset(pdst, 0, sizeof(pdst));
+ silc_cipher_set_iv(cipher, iv4);
+ assert(silc_cipher_set_key(cipher, key4, key4_len, TRUE));
+ assert(silc_cipher_encrypt(cipher, p4, dst, p4_len, NULL));
+ SILC_LOG_DEBUG(("block len %d, key len %d, name %s",
+ silc_cipher_get_block_len(cipher),
+ silc_cipher_get_key_len(cipher),
+ silc_cipher_get_name(cipher)));
+ SILC_LOG_HEXDUMP(("Plaintext"), (unsigned char *)p4, p4_len);
+ SILC_LOG_HEXDUMP(("Ciphertext"), (unsigned char *)dst, p4_len);
+ SILC_LOG_HEXDUMP(("Expected ciphertext"), (unsigned char *)c4, p4_len);
+ if (memcmp(dst, c4, p4_len)) {
+ SILC_LOG_DEBUG(("Encrypt failed"));
+ goto err;
+ }
+ SILC_LOG_DEBUG(("Encrypt is successful"));
+ silc_cipher_set_iv(cipher, iv4);
+ assert(silc_cipher_decrypt(cipher, dst, pdst, p4_len, NULL));
+ SILC_LOG_HEXDUMP(("Decrypted plaintext"), (unsigned char *)pdst, p4_len);
+ SILC_LOG_HEXDUMP(("Expected plaintext"), (unsigned char *)p4, p4_len);
+ if (memcmp(pdst, p4, p4_len)) {
+ SILC_LOG_DEBUG(("Decrypt failed"));
+ goto err;
+ }
+ SILC_LOG_DEBUG(("Decrypt is successful"));
+ silc_cipher_free(cipher);
+
+ SILC_LOG_DEBUG(("Allocating aes-256-ctr cipher"));
+ if (!silc_cipher_alloc("aes-256-ctr", &cipher)) {
+ SILC_LOG_DEBUG(("Allocating aes-256-ctr cipher failed"));
+ goto err;
+ }
+ if (!silc_cipher_alloc("aes-256-ctr", &cipher2)) {
+ SILC_LOG_DEBUG(("Allocating aes-256-ctr cipher failed"));
+ goto err;
+ }
+
+ /* Fifth test vector */
+ SILC_LOG_DEBUG(("Fifth test vector"));
+ memset(dst, 0, sizeof(dst));
+ memset(pdst, 0, sizeof(pdst));
+ silc_cipher_set_iv(cipher, iv5);
+ assert(silc_cipher_set_key(cipher, key5, key5_len, TRUE));
+ assert(silc_cipher_set_key(cipher2, key5, key5_len, FALSE));
+ assert(silc_cipher_encrypt(cipher, p5, dst, p5_len, NULL));
+ SILC_LOG_DEBUG(("block len %d, key len %d, name %s",
+ silc_cipher_get_block_len(cipher),
+ silc_cipher_get_key_len(cipher),
+ silc_cipher_get_name(cipher)));
+ SILC_LOG_HEXDUMP(("Plaintext"), (unsigned char *)p5, p5_len);
+ SILC_LOG_HEXDUMP(("Ciphertext"), (unsigned char *)dst, p5_len);
+ SILC_LOG_HEXDUMP(("Expected ciphertext"), (unsigned char *)c5, p5_len);
+ if (memcmp(dst, c5, p5_len)) {
+ SILC_LOG_DEBUG(("Encrypt failed"));
+ goto err;
+ }
+ SILC_LOG_DEBUG(("Encrypt is successful"));
+ silc_cipher_set_iv(cipher2, iv5);
+ assert(silc_cipher_decrypt(cipher2, dst, pdst, p5_len, NULL));
+ SILC_LOG_HEXDUMP(("Decrypted plaintext"), (unsigned char *)pdst, p5_len);
+ SILC_LOG_HEXDUMP(("Expected plaintext"), (unsigned char *)p5, p5_len);
+ if (memcmp(pdst, p5, p5_len)) {
+ SILC_LOG_DEBUG(("Decrypt failed"));
+ goto err;
+ }
+ SILC_LOG_DEBUG(("Decrypt is successful"));
+ silc_cipher_free(cipher2);
success = TRUE;
/* Sets the key for the cipher. */
-SILC_CIPHER_API_SET_KEY(twofish)
+SILC_CIPHER_API_SET_KEY(twofish_cbc)
{
SilcUInt32 k[8];
/* Returns the size of the cipher context. */
-SILC_CIPHER_API_CONTEXT_LEN(twofish)
+SILC_CIPHER_API_CONTEXT_LEN(twofish_cbc)
{
return sizeof(TwofishContext);
}
/* Encrypts with the cipher in CBC mode. Source and destination buffers
maybe one and same. */
-SILC_CIPHER_API_ENCRYPT_CBC(twofish)
+SILC_CIPHER_API_ENCRYPT(twofish_cbc)
{
SilcUInt32 tiv[4];
int i;
+ SILC_ASSERT((len & (16 - 1)) == 0);
+ if (len & (16 - 1))
+ return FALSE;
SILC_CBC_GET_IV(tiv, iv);
SILC_CBC_ENC_PRE(tiv, src);
/* Decrypts with the cipher in CBC mode. Source and destination buffers
maybe one and same. */
-SILC_CIPHER_API_DECRYPT_CBC(twofish)
+SILC_CIPHER_API_DECRYPT(twofish_cbc)
{
SilcUInt32 tmp[4], tmp2[4], tiv[4];
int i;
+ if (len & (16 - 1))
+ return FALSE;
+
SILC_CBC_GET_IV(tiv, iv);
SILC_CBC_DEC_PRE(tmp, src);
* SILC Crypto API for Twofish
*/
-SILC_CIPHER_API_SET_KEY(twofish);
-SILC_CIPHER_API_CONTEXT_LEN(twofish);
-SILC_CIPHER_API_ENCRYPT_CBC(twofish);
-SILC_CIPHER_API_DECRYPT_CBC(twofish);
+SILC_CIPHER_API_SET_KEY(twofish_cbc);
+SILC_CIPHER_API_CONTEXT_LEN(twofish_cbc);
+SILC_CIPHER_API_ENCRYPT(twofish_cbc);
+SILC_CIPHER_API_DECRYPT(twofish_cbc);
#endif
silc_log_set_debug_string("*fsm*,*async*");
}
-{
-#define SSILC_GET32_MSB(l, cp) \
-do { \
- (l) = ((SilcUInt32)(SilcUInt8)(cp)[3]) << 24 \
- | ((SilcUInt32)(SilcUInt8)(cp)[2] << 16) \
- | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8) \
- | ((SilcUInt32)(SilcUInt8)(cp)[0]); \
-} while(0)
- unsigned char tmp[8], tmp2[8];
- SilcUInt32 t1, t2, t3, t4;
-
- tmp[0] = 0x11;
- tmp[1] = 0x22;
- tmp[2] = 0x33;
- tmp[3] = 0x44;
- tmp[4] = 0x55;
- tmp[5] = 0x66;
- tmp[6] = 0x77;
- tmp[7] = 0x88;
-
- SILC_LOG_HEXDUMP(("DATA"), tmp, 4);
-
- SILC_GET32_LSB(t1, tmp);
- SILC_LOG_DEBUG(("GET_LSB: %x", t1));
-
- SSILC_GET32_MSB(t1, tmp);
- SILC_LOG_DEBUG(("GET_MSB: %x", t1));
-
- SILC_PUT32_LSB(t1, tmp2);
- SILC_LOG_HEXDUMP(("PUT_LSB"), tmp2, 4);
-
- SILC_PUT32_MSB(t1, tmp2);
- SILC_LOG_HEXDUMP(("PUT_MSB"), tmp2, 4);
-
- exit(1);
-}
-
SILC_LOG_DEBUG(("Allocating scheduler"));
schedule = silc_schedule_init(0, NULL);