Issue 09/09/2006
*/
-#include "silc.h"
-#include "rijndael_internal.h"
+#include "silccrypto.h"
+#include "aes_internal.h"
#include "aes.h"
/*
* SILC Crypto API for AES
*/
-/* CBC mode */
-
/* Sets the key for the cipher. */
-SILC_CIPHER_API_SET_KEY(aes_cbc)
+SILC_CIPHER_API_SET_KEY(aes)
{
- if (encryption)
+ switch (ops->mode) {
+ case SILC_CIPHER_MODE_CTR:
+ case SILC_CIPHER_MODE_CFB:
aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
- else
- aes_decrypt_key(key, keylen, &((AesContext *)context)->u.dec);
+ break;
+
+ case SILC_CIPHER_MODE_CBC:
+ case SILC_CIPHER_MODE_ECB:
+ if (encryption)
+ aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
+ else
+ aes_decrypt_key(key, keylen, &((AesContext *)context)->u.dec);
+ break;
+
+ default:
+ return FALSE;
+ }
return TRUE;
}
/* Sets IV for the cipher. */
-SILC_CIPHER_API_SET_IV(aes_cbc)
+SILC_CIPHER_API_SET_IV(aes)
{
+ AesContext *aes = context;
-}
+ switch (ops->mode) {
-/* Returns the size of the cipher context. */
+ case SILC_CIPHER_MODE_CTR:
+ case SILC_CIPHER_MODE_CFB:
+ /* Starts new block. */
+ aes->u.enc.inf.b[2] = 16;
+ break;
-SILC_CIPHER_API_CONTEXT_LEN(aes_cbc)
-{
- return sizeof(AesContext);
+ default:
+ break;
+ }
}
-/* Encrypts with the cipher in CBC mode. Source and destination buffers
- maybe one and same. */
+/* Initialize */
-SILC_CIPHER_API_ENCRYPT(aes_cbc)
+SILC_CIPHER_API_INIT(aes)
{
- int nb = len >> 4;
-
- SILC_ASSERT((len & (16 - 1)) == 0);
- if (len & (16 - 1))
- return FALSE;
+ AesContext *aes = silc_calloc(1, sizeof(AesContext));
+ if (aes)
+ aes->u.enc.inf.b[2] = 16;
+}
- while(nb--) {
- lp32(iv)[0] ^= lp32(src)[0];
- lp32(iv)[1] ^= lp32(src)[1];
- lp32(iv)[2] ^= lp32(src)[2];
- lp32(iv)[3] ^= lp32(src)[3];
- aes_encrypt(iv, iv, &((AesContext *)context)->u.enc);
- memcpy(dst, iv, 16);
- src += 16;
- dst += 16;
- }
+/* Unnitialize */
- return TRUE;
+SILC_CIPHER_API_UNINIT(aes)
+{
+ AesContext *aes = context;
+ memset(aes, 0, sizeof(*aes));
+ silc_free(aes);
}
-/* Decrypts with the cipher in CBC mode. Source and destination buffers
- maybe one and same. */
+/* Encrypts with the cipher. Source and destination buffers maybe one and
+ same. */
-SILC_CIPHER_API_DECRYPT(aes_cbc)
+SILC_CIPHER_API_ENCRYPT(aes)
{
- unsigned char tmp[16];
- int nb = len >> 4;
+ AesContext *aes = context;
+ int i;
- if (len & (16 - 1))
- return FALSE;
+ switch (ops->mode) {
+ case SILC_CIPHER_MODE_CTR:
+ SILC_CTR_MSB_128_8(iv, cipher->block, aes->u.enc.inf.b[2], src, dst,
+ aes_encrypt(iv, cipher->block, &aes->u.enc));
+ break;
- while(nb--) {
- memcpy(tmp, src, 16);
- aes_decrypt(src, dst, &((AesContext *)context)->u.dec);
- lp32(dst)[0] ^= lp32(iv)[0];
- lp32(dst)[1] ^= lp32(iv)[1];
- lp32(dst)[2] ^= lp32(iv)[2];
- lp32(dst)[3] ^= lp32(iv)[3];
- memcpy(iv, tmp, 16);
- src += 16;
- dst += 16;
- }
+ case SILC_CIPHER_MODE_ECB:
+ {
+ SilcUInt32 nb = len >> 4;
- return TRUE;
-}
+ while (nb--) {
+ aes_encrypt(src, dst, &aes->u.enc);
+ src += 16;
+ dst += 16;
+ }
+ }
+ break;
-/* CTR mode */
+ case SILC_CIPHER_MODE_CBC:
+ {
+ SilcUInt32 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];
+ lp32(iv)[2] ^= lp32(src)[2];
+ lp32(iv)[3] ^= lp32(src)[3];
+ aes_encrypt(iv, iv, &aes->u.enc);
+ memcpy(dst, iv, 16);
+ src += 16;
+ dst += 16;
+ }
+ }
+ break;
-/* Sets the key for the cipher. */
+ case SILC_CIPHER_MODE_CFB:
+ SILC_CFB_ENC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
+ aes_encrypt(iv, iv, &aes->u.enc));
+ break;
+
+ default:
+ return FALSE;
+ }
-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;
}
-/* Sets IV for the cipher. */
+/* Decrypts with the cipher. Source and destination buffers maybe one
+ and same. */
-SILC_CIPHER_API_SET_IV(aes_ctr)
+SILC_CIPHER_API_DECRYPT(aes)
{
AesContext *aes = context;
- /* Starts new block. */
- aes->u.enc.inf.b[2] = 0;
-}
-
-/* Returns the size of the cipher context. */
-
-SILC_CIPHER_API_CONTEXT_LEN(aes_ctr)
-{
- return sizeof(AesContext);
-}
+ switch (ops->mode) {
+ case SILC_CIPHER_MODE_CTR:
+ return silc_aes_encrypt(cipher, ops, context, src, dst, len, iv);
+ break;
-/* Encrypts with the cipher in CTR mode. Source and destination buffers
- maybe one and same. Assumes MSB first ordered counter. */
+ case SILC_CIPHER_MODE_ECB:
+ {
+ SilcUInt32 nb = len >> 4;
-SILC_CIPHER_API_ENCRYPT(aes_ctr)
-{
- AesContext *aes = context;
- SilcUInt32 ctr[4];
- int i = 16;
-
- 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;
+ while (nb--) {
+ aes_decrypt(src, dst, &aes->u.dec);
+ src += 16;
+ dst += 16;
+ }
}
- *dst++ = *src++ ^ iv[i++];
- }
- aes->u.enc.inf.b[2] = i;
+ break;
- 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);
+ case SILC_CIPHER_MODE_CBC:
+ {
+ unsigned char tmp[16];
+ SilcUInt32 nb = len >> 4;
+
+ if (len & (16 - 1))
+ return FALSE;
+
+ while(nb--) {
+ memcpy(tmp, src, 16);
+ aes_decrypt(src, dst, &aes->u.dec);
+ lp32(dst)[0] ^= lp32(iv)[0];
+ lp32(dst)[1] ^= lp32(iv)[1];
+ lp32(dst)[2] ^= lp32(iv)[2];
+ lp32(dst)[3] ^= lp32(iv)[3];
+ memcpy(iv, tmp, 16);
+ src += 16;
+ dst += 16;
+ }
+ }
+ break;
- return TRUE;
-}
+ case SILC_CIPHER_MODE_CFB:
+ SILC_CFB_DEC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
+ aes_encrypt(iv, iv, &aes->u.enc));
+ break;
-/* Decrypts with the cipher in CTR mode. Source and destination buffers
- maybe one and same. */
+ default:
+ return FALSE;
+ }
-SILC_CIPHER_API_DECRYPT(aes_ctr)
-{
- return silc_aes_ctr_encrypt(context, src, dst, len, iv);
+ return TRUE;
}
/****************************************************************************/
#define d_4(t,n,b,e,f,g,h) ALIGN const XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }
ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
-#ifdef SILC_ASM_AES
+#ifdef SILC_AES_ASM
d_1(uint_8t, t_dec(i,box), isb_data, h0);
-#endif /* SILC_ASM_AES */
+#endif /* SILC_AES_ASM */
d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
ke4(cx->ks, 6); ke4(cx->ks, 7);
ke4(cx->ks, 8);
ke4(cx->ks, 9);
- cx->inf.l = 0;
cx->inf.b[0] = 10 * 16;
}
ke6(cx->ks, 4); ke6(cx->ks, 5);
ke6(cx->ks, 6);
kef6(cx->ks, 7);
- cx->inf.l = 0;
cx->inf.b[0] = 12 * 16;
}
ke8(cx->ks, 2); ke8(cx->ks, 3);
ke8(cx->ks, 4); ke8(cx->ks, 5);
kef8(cx->ks, 6);
- cx->inf.l = 0;
cx->inf.b[0] = 14 * 16;
}
kd4(cx->ks, 4); kd4(cx->ks, 5);
kd4(cx->ks, 6); kd4(cx->ks, 7);
kd4(cx->ks, 8); kdl4(cx->ks, 9);
- cx->inf.l = 0;
cx->inf.b[0] = 10 * 16;
}
kd6(cx->ks, 2); kd6(cx->ks, 3);
kd6(cx->ks, 4); kd6(cx->ks, 5);
kd6(cx->ks, 6); kdl6(cx->ks, 7);
- cx->inf.l = 0;
cx->inf.b[0] = 12 * 16;
}
kd8(cx->ks, 2); kd8(cx->ks, 3);
kd8(cx->ks, 4); kd8(cx->ks, 5);
kdl8(cx->ks, 6);
- cx->inf.l = 0;
cx->inf.b[0] = 14 * 16;
}
}
}
-#ifndef SILC_ASM_AES
+#ifndef SILC_AES_ASM
/* C version of AES */
#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
}
#endif
-#endif /* SILC_ASM_AES */
+#endif /* SILC_AES_ASM */