X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Faes.c;h=f60f395226978acba8f984369b174b2ca916a121;hb=9f20f0382b6229eca740925a73f96294f6dcedc6;hp=49692129d0cc55e857a838688c0c89ac0f745b8d;hpb=1c41d8bb1303a036c2c16abe416fdb7628f75c3d;p=crypto.git diff --git a/lib/silccrypt/aes.c b/lib/silccrypt/aes.c index 49692129..f60f3952 100644 --- a/lib/silccrypt/aes.c +++ b/lib/silccrypt/aes.c @@ -33,174 +33,192 @@ 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; + + 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; -/* CTR mode */ + 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; -/* Sets the key for the cipher. */ + 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; -} + switch (ops->mode) { + case SILC_CIPHER_MODE_CTR: + return silc_aes_encrypt(cipher, ops, context, src, dst, len, iv); + break; -/* Returns the size of the cipher context. */ + case SILC_CIPHER_MODE_ECB: + { + SilcUInt32 nb = len >> 4; -SILC_CIPHER_API_CONTEXT_LEN(aes_ctr) -{ - return sizeof(AesContext); -} + while (nb--) { + aes_decrypt(src, dst, &aes->u.dec); + src += 16; + dst += 16; + } + } + break; -/* Encrypts with the cipher in CTR mode. Source and destination buffers - may be one and same. Assumes MSB first ordered counter. */ + 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; -SILC_CIPHER_API_ENCRYPT(aes_ctr) -{ - AesContext *aes = context; - SilcUInt32 ctr[4]; - int i; + 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; - 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++]; + default: + return FALSE; } - 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) @@ -248,7 +266,6 @@ AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]) 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; } @@ -280,7 +297,6 @@ AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]) 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; } @@ -315,7 +331,6 @@ AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]) 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; } @@ -381,7 +396,6 @@ AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]) 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; } @@ -440,7 +454,6 @@ AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]) 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; } @@ -508,7 +521,6 @@ AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]) 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; }