X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Faes.c;h=52d0397b917e0068fe3dbd27115936776e2784b7;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=9fc9f1e663ec0450e0f0523b35c59616e2b18a9a;hpb=97ca3ffe0ce65ac0c5fa3274284825537e996c78;p=silc.git diff --git a/lib/silccrypt/aes.c b/lib/silccrypt/aes.c index 9fc9f1e6..52d0397b 100644 --- a/lib/silccrypt/aes.c +++ b/lib/silccrypt/aes.c @@ -45,11 +45,48 @@ SILC_CIPHER_API_SET_KEY(aes) { - aes_encrypt_key(key, keylen, &((AesContext *)context)->enc); - aes_decrypt_key(key, keylen, &((AesContext *)context)->dec); + switch (cipher->mode) { + case SILC_CIPHER_MODE_CBC: + if (encryption) + aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc); + else + aes_decrypt_key(key, keylen, &((AesContext *)context)->u.dec); + break; + + case SILC_CIPHER_MODE_CTR: + case SILC_CIPHER_MODE_CFB: + aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc); + break; + + default: + return FALSE; + } return TRUE; } +/* Sets IV for the cipher. */ + +SILC_CIPHER_API_SET_IV(aes) +{ + AesContext *aes = context; + + switch (cipher->mode) { + + case SILC_CIPHER_MODE_CTR: + /* Starts new block. */ + aes->u.enc.inf.b[2] = 0; + break; + + case SILC_CIPHER_MODE_CFB: + /* Starts new block. */ + aes->u.enc.inf.b[2] = 16; + break; + + default: + break; + } +} + /* Returns the size of the cipher context. */ SILC_CIPHER_API_CONTEXT_LEN(aes) @@ -57,45 +94,94 @@ SILC_CIPHER_API_CONTEXT_LEN(aes) return sizeof(AesContext); } -/* Encrypts 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_ENCRYPT_CBC(aes) +SILC_CIPHER_API_ENCRYPT(aes) { - int nb = len >> 4; - - 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)->enc); - memcpy(dst, iv, 16); - src += 16; - dst += 16; + AesContext *aes = context; + SilcUInt32 ctr[4]; + + switch (cipher->mode) { + case SILC_CIPHER_MODE_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]; + 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; + + case SILC_CIPHER_MODE_CTR: + SILC_CTR_MSB_128_8(iv, ctr, iv, aes->u.enc.inf.b[2], src, dst, + aes_encrypt(iv, iv, &aes->u.enc)); + break; + + 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; } return TRUE; } -/* Decrypts with the cipher in CBC mode. Source and destination buffers - maybe one and same. */ +/* Decrypts with the cipher. Source and destination buffers maybe one + and same. */ -SILC_CIPHER_API_DECRYPT_CBC(aes) +SILC_CIPHER_API_DECRYPT(aes) { - unsigned char tmp[16]; - int nb = len >> 4; - - while(nb--) { - memcpy(tmp, src, 16); - aes_decrypt(src, dst, &((AesContext *)context)->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; + AesContext *aes = context; + + switch (cipher->mode) { + case SILC_CIPHER_MODE_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, &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; + + case SILC_CIPHER_MODE_CTR: + return silc_aes_encrypt(cipher, context, src, dst, len, iv); + break; + + 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; + + default: + return FALSE; } return TRUE; @@ -118,9 +204,9 @@ extern "C" #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); @@ -148,7 +234,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; } @@ -180,7 +265,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; } @@ -215,7 +299,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; } @@ -281,7 +364,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; } @@ -340,7 +422,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; } @@ -408,7 +489,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; } @@ -422,7 +502,7 @@ AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ct } } -#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]) @@ -531,4 +611,4 @@ AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_de } #endif -#endif /* SILC_ASM_AES */ +#endif /* SILC_AES_ASM */