From: Pekka Riikonen Date: Tue, 19 Dec 2006 18:41:20 +0000 (+0000) Subject: Added CTR mode to AES. Simplified cipher implementation API more. X-Git-Tag: 1.2.beta1~532 X-Git-Url: http://git.silcnet.org/gitweb/?p=crypto.git;a=commitdiff_plain;h=22df1889422ee8031d08d1d6f08117c79dbade96 Added CTR mode to AES. Simplified cipher implementation API more. --- diff --git a/apps/irssi/silc.conf b/apps/irssi/silc.conf index ba405d71..30cc7c5f 100644 --- a/apps/irssi/silc.conf +++ b/apps/irssi/silc.conf @@ -208,7 +208,7 @@ statusbar = { # settings = { "server" = { - crypto_default_cipher = "aes-256-cbc"; + crypto_default_cipher = "aes-256-ctr"; crypto_default_hash = "sha1"; crypto_default_hmac = "hmac-sha1-96"; }; diff --git a/lib/silccrypt/aes.c b/lib/silccrypt/aes.c index d05bb768..bb78fd16 100644 --- a/lib/silccrypt/aes.c +++ b/lib/silccrypt/aes.c @@ -41,9 +41,11 @@ * 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); @@ -54,7 +56,7 @@ SILC_CIPHER_API_SET_KEY(aes) /* Returns the size of the cipher context. */ -SILC_CIPHER_API_CONTEXT_LEN(aes) +SILC_CIPHER_API_CONTEXT_LEN(aes_cbc) { return sizeof(AesContext); } @@ -62,10 +64,14 @@ SILC_CIPHER_API_CONTEXT_LEN(aes) /* 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]; @@ -83,11 +89,14 @@ SILC_CIPHER_API_ENCRYPT_CBC(aes) /* 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); @@ -103,6 +112,78 @@ SILC_CIPHER_API_DECRYPT_CBC(aes) 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) diff --git a/lib/silccrypt/aes.h b/lib/silccrypt/aes.h index 18666454..d5bf528f 100644 --- a/lib/silccrypt/aes.h +++ b/lib/silccrypt/aes.h @@ -21,12 +21,16 @@ #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 diff --git a/lib/silccrypt/blowfish.c b/lib/silccrypt/blowfish.c index 25b9deab..860787a3 100644 --- a/lib/silccrypt/blowfish.c +++ b/lib/silccrypt/blowfish.c @@ -43,7 +43,7 @@ /* 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; @@ -51,7 +51,7 @@ SILC_CIPHER_API_SET_KEY(blowfish) /* Returns the size of the cipher context. */ -SILC_CIPHER_API_CONTEXT_LEN(blowfish) +SILC_CIPHER_API_CONTEXT_LEN(blowfish_cbc) { return sizeof(BlowfishContext); } @@ -59,7 +59,7 @@ SILC_CIPHER_API_CONTEXT_LEN(blowfish) /* 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; @@ -84,7 +84,7 @@ SILC_CIPHER_API_ENCRYPT_CBC(blowfish) /* 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; diff --git a/lib/silccrypt/blowfish.h b/lib/silccrypt/blowfish.h index 6f3db654..2a76db06 100644 --- a/lib/silccrypt/blowfish.h +++ b/lib/silccrypt/blowfish.h @@ -24,9 +24,9 @@ * 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 diff --git a/lib/silccrypt/cast.c b/lib/silccrypt/cast.c index 52207887..e1e1a816 100644 --- a/lib/silccrypt/cast.c +++ b/lib/silccrypt/cast.c @@ -70,7 +70,7 @@ Mean: 674 cycles = 38.0 mbits/sec /* Sets the key for the cipher. */ -SILC_CIPHER_API_SET_KEY(cast) +SILC_CIPHER_API_SET_KEY(cast_cbc) { SilcUInt32 k[8]; @@ -82,7 +82,7 @@ SILC_CIPHER_API_SET_KEY(cast) /* Returns the size of the cipher context. */ -SILC_CIPHER_API_CONTEXT_LEN(cast) +SILC_CIPHER_API_CONTEXT_LEN(cast_cbc) { return sizeof(CastContext); } @@ -90,11 +90,15 @@ SILC_CIPHER_API_CONTEXT_LEN(cast) /* 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); @@ -115,11 +119,14 @@ SILC_CIPHER_API_ENCRYPT_CBC(cast) /* 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); diff --git a/lib/silccrypt/cast.h b/lib/silccrypt/cast.h index 0630628a..092a1cf0 100644 --- a/lib/silccrypt/cast.h +++ b/lib/silccrypt/cast.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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 @@ -24,9 +24,9 @@ * 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 diff --git a/lib/silccrypt/none.c b/lib/silccrypt/none.c index 3c45849a..d8b79012 100644 --- a/lib/silccrypt/none.c +++ b/lib/silccrypt/none.c @@ -34,13 +34,13 @@ SILC_CIPHER_API_CONTEXT_LEN(none) 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; diff --git a/lib/silccrypt/none.h b/lib/silccrypt/none.h index 261b1c16..b0f3a38b 100644 --- a/lib/silccrypt/none.h +++ b/lib/silccrypt/none.h @@ -16,24 +16,6 @@ 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 @@ -44,7 +26,7 @@ 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 diff --git a/lib/silccrypt/rc5.c b/lib/silccrypt/rc5.c index 30c5dffd..ea377c58 100644 --- a/lib/silccrypt/rc5.c +++ b/lib/silccrypt/rc5.c @@ -48,7 +48,7 @@ /* Sets the key for the cipher. */ -SILC_CIPHER_API_SET_KEY(rc5) +SILC_CIPHER_API_SET_KEY(rc5_cbc) { SilcUInt32 k[8]; @@ -60,7 +60,7 @@ SILC_CIPHER_API_SET_KEY(rc5) /* Returns the size of the cipher context. */ -SILC_CIPHER_API_CONTEXT_LEN(rc5) +SILC_CIPHER_API_CONTEXT_LEN(rc5_cbc) { return sizeof(RC5Context); } @@ -68,7 +68,7 @@ SILC_CIPHER_API_CONTEXT_LEN(rc5) /* 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; @@ -93,7 +93,7 @@ SILC_CIPHER_API_ENCRYPT_CBC(rc5) /* 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; diff --git a/lib/silccrypt/rc5.h b/lib/silccrypt/rc5.h index ea36d808..d269c661 100644 --- a/lib/silccrypt/rc5.h +++ b/lib/silccrypt/rc5.h @@ -24,9 +24,9 @@ * 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 diff --git a/lib/silccrypt/silccipher.c b/lib/silccrypt/silccipher.c index 1832566f..e967e831 100644 --- a/lib/silccrypt/silccipher.c +++ b/lib/silccrypt/silccipher.c @@ -33,50 +33,31 @@ struct SilcCipherStruct { 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 @@ -311,9 +292,6 @@ SilcBool silc_cipher_encrypt(SilcCipher cipher, const unsigned char *src, 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); } @@ -324,8 +302,6 @@ SilcBool silc_cipher_decrypt(SilcCipher cipher, const unsigned char *src, 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); } diff --git a/lib/silccrypt/silccipher.h b/lib/silccrypt/silccipher.h index c020d280..3c557f23 100644 --- a/lib/silccrypt/silccipher.h +++ b/lib/silccrypt/silccipher.h @@ -51,9 +51,9 @@ typedef struct { 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; @@ -79,31 +79,34 @@ extern DLLAPI const SilcCipherObject silc_default_ciphers[]; 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 */ diff --git a/lib/silccrypt/tests/test_aes.c b/lib/silccrypt/tests/test_aes.c index 1048cc51..0a104598 100644 --- a/lib/silccrypt/tests/test_aes.c +++ b/lib/silccrypt/tests/test_aes.c @@ -19,11 +19,36 @@ const unsigned char p2[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c 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; @@ -36,23 +61,23 @@ int main(int argc, char **argv) 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), @@ -66,8 +91,8 @@ int main(int argc, char **argv) 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)) { @@ -82,7 +107,8 @@ int main(int argc, char **argv) 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), @@ -96,8 +122,8 @@ int main(int argc, char **argv) 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)) { @@ -105,6 +131,116 @@ int main(int argc, char **argv) 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; diff --git a/lib/silccrypt/twofish.c b/lib/silccrypt/twofish.c index e388a951..c5243812 100644 --- a/lib/silccrypt/twofish.c +++ b/lib/silccrypt/twofish.c @@ -49,7 +49,7 @@ Mean: 378 cycles = 67.8 mbits/sec /* Sets the key for the cipher. */ -SILC_CIPHER_API_SET_KEY(twofish) +SILC_CIPHER_API_SET_KEY(twofish_cbc) { SilcUInt32 k[8]; @@ -61,7 +61,7 @@ SILC_CIPHER_API_SET_KEY(twofish) /* Returns the size of the cipher context. */ -SILC_CIPHER_API_CONTEXT_LEN(twofish) +SILC_CIPHER_API_CONTEXT_LEN(twofish_cbc) { return sizeof(TwofishContext); } @@ -69,11 +69,14 @@ SILC_CIPHER_API_CONTEXT_LEN(twofish) /* 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); @@ -94,11 +97,14 @@ SILC_CIPHER_API_ENCRYPT_CBC(twofish) /* 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); diff --git a/lib/silccrypt/twofish.h b/lib/silccrypt/twofish.h index 2f67d7ab..ba845960 100644 --- a/lib/silccrypt/twofish.h +++ b/lib/silccrypt/twofish.h @@ -24,9 +24,9 @@ * 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 diff --git a/lib/silcutil/tests/test_silcfsm.c b/lib/silcutil/tests/test_silcfsm.c index 04cd9806..df11891b 100644 --- a/lib/silcutil/tests/test_silcfsm.c +++ b/lib/silcutil/tests/test_silcfsm.c @@ -386,43 +386,6 @@ int main(int argc, char **argv) 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);